@afncdelacru/brady-chat 0.1.6 → 0.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -35,7 +35,7 @@ var import_jsx_runtime = require("react/jsx-runtime");
35
35
  var BradyChatContext = (0, import_react.createContext)(void 0);
36
36
  var initialMessages = [
37
37
  {
38
- type: "brady",
38
+ type: "user",
39
39
  text: "introduce"
40
40
  }
41
41
  ];
@@ -1199,36 +1199,7 @@ I'll focus on ways to increase ${isBranchManager ? "profit" : "income"} using ${
1199
1199
  action: () => handleQuickSuggestion(s.prompt)
1200
1200
  }));
1201
1201
  }
1202
- return [
1203
- {
1204
- text: "How does AFN help LOs grow?",
1205
- action: () => handleQuickSuggestion("How does AFN help LOs grow?")
1206
- },
1207
- {
1208
- text: "How does AFN help branch managers earn more?",
1209
- action: () => handleQuickSuggestion("How does AFN help branch managers earn more?")
1210
- },
1211
- {
1212
- text: "Why do people choose AFN?",
1213
- action: () => handleQuickSuggestion("Why do people choose AFN?")
1214
- },
1215
- {
1216
- text: "The AFN Advantage",
1217
- action: () => handleQuickSuggestion("See How AFN Supports Loan Officer Success")
1218
- },
1219
- {
1220
- text: "Why AFN?",
1221
- action: () => handleQuickSuggestion("Why AFN?")
1222
- },
1223
- {
1224
- text: "How does AI help me earn more?",
1225
- action: () => handleQuickSuggestion("How does AI help me earn more?")
1226
- },
1227
- {
1228
- text: "What makes AFN different?",
1229
- action: () => handleQuickSuggestion("What makes AFN different?")
1230
- }
1231
- ];
1202
+ return [];
1232
1203
  };
1233
1204
  const initialSuggestions = buildSuggestions();
1234
1205
  const postSubmitSuggestions = buildSuggestions();
@@ -1251,9 +1222,6 @@ I'll focus on ways to increase ${isBranchManager ? "profit" : "income"} using ${
1251
1222
  }
1252
1223
  ) : null;
1253
1224
  if (isHidden) return null;
1254
- if (!bradyHealthy) {
1255
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "fixed top-0 right-0 w-full md:w-[360px] h-screen flex flex-col bg-gradient-to-br dark:from-zinc-900 dark:to-zinc-800 from-white to-zinc-50 border-l md:border-l dark:border-zinc-700 border-zinc-300 shadow-2xl z-[100] overflow-hidden transition-all duration-300 items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "text-center text-zinc-500 dark:text-zinc-400 text-lg font-medium", children: "Sorry, Brady AI is currently unavailable." }) });
1256
- }
1257
1225
  return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "fixed top-0 right-0 w-full md:w-[360px] h-screen flex flex-col bg-gradient-to-br dark:from-zinc-900 dark:to-zinc-800 from-white to-zinc-50 border-l md:border-l dark:border-zinc-700 border-zinc-300 shadow-2xl z-[100] overflow-hidden transition-all duration-300", children: [
1258
1226
  /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex items-center justify-between px-4 py-3 border-b dark:border-zinc-800 border-zinc-200 dark:bg-zinc-950/80 bg-white/95 backdrop-blur-lg", children: [
1259
1227
  /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex items-center gap-3", children: [
@@ -1321,6 +1289,7 @@ I'll focus on ways to increase ${isBranchManager ? "profit" : "income"} using ${
1321
1289
  ] })
1322
1290
  ] }),
1323
1291
  modeBadge && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "px-4 py-2 border-b dark:border-zinc-800 border-zinc-200", children: modeBadge }),
1292
+ !bradyHealthy && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "fixed top-0 right-0 w-full md:w-[360px] h-screen flex flex-col bg-gradient-to-br dark:from-zinc-900 dark:to-zinc-800 from-white to-zinc-50 border-l md:border-l dark:border-zinc-700 border-zinc-300 shadow-2xl z-[100] overflow-hidden transition-all duration-300 items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "text-center text-zinc-500 dark:text-zinc-400 text-lg font-medium", children: "Sorry, Brady AI is currently unavailable." }) }),
1324
1293
  /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex-1 overflow-y-auto p-4 space-y-4", children: [
1325
1294
  /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react12.AnimatePresence, { children: messages.map((msg, idx) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1326
1295
  import_react12.motion.div,
@@ -1332,7 +1301,7 @@ I'll focus on ways to increase ${isBranchManager ? "profit" : "income"} using ${
1332
1301
  "div",
1333
1302
  {
1334
1303
  className: `px-4 py-3 rounded-2xl whitespace-pre-line ${msg.type === "user" ? "bg-[#8B5CF6] text-white rounded-br-sm" : "dark:bg-zinc-800 bg-zinc-100 dark:text-zinc-100 text-zinc-900 rounded-bl-sm"}`,
1335
- children: msg.text
1304
+ children: msg.text === "introduce" ? "" : msg.text
1336
1305
  }
1337
1306
  )
1338
1307
  },
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/lib/BradyChatContext.tsx","../src/lib/EnhancedBradyChat.tsx","../src/lib/api/afnBradyApi.ts","../src/lib/api/bradyHealth.ts","../src/lib/InfoRequestForm.tsx","../src/lib/LeadershipCallForm.tsx","../src/lib/PersonalizedOverviewForm.tsx","../src/lib/QuickSuggestions.tsx","../src/lib/ModePromptTree.tsx","../src/lib/ImageWithFallback.tsx"],"sourcesContent":["export * from './lib/BradyChatContext';\r\nexport * from './lib/EnhancedBradyChat';\r\nexport * from './lib/api/afnBradyApi';\r\nexport * from './lib/api/bradyHealth';\r\n","'use client';\r\n\r\nimport React, { createContext, useContext, useState, ReactNode } from 'react';\r\n\r\nexport type ChatWorkflowType =\r\n | 'free'\r\n | 'info-request'\r\n | 'leadership-call'\r\n | 'personalized-overview-request'\r\n | 'earnings-mode'\r\n | 'profit-mode';\r\nexport type ModeType = 'none' | 'earnings' | 'profit';\r\nexport type ModeStep = 'initial' | 'volume' | 'comp' | 'economics' | 'calculator' | 'complete';\r\n\r\nexport interface ChatMessage {\r\n type: 'user' | 'brady' | 'form';\r\n text?: string;\r\n component?: ReactNode;\r\n}\r\n\r\ninterface ModeData {\r\n volume?: number;\r\n comp?: number;\r\n margin?: number;\r\n grossProfit?: number;\r\n opEx?: number;\r\n volumeMultiplier?: number;\r\n}\r\n\r\ninterface BradyChatContextType {\r\n workflowType: ChatWorkflowType;\r\n messages: ChatMessage[];\r\n startWorkflow: (workflow: ChatWorkflowType) => void;\r\n addMessage: (message: ChatMessage) => void;\r\n setWorkflow: (workflow: ChatWorkflowType) => void;\r\n resetChat: () => void;\r\n // Mode system\r\n activeMode: ModeType;\r\n modeStep: ModeStep;\r\n modeData: ModeData;\r\n activateMode: (mode: ModeType) => void;\r\n setModeStep: (step: ModeStep) => void;\r\n updateModeData: (data: Partial<ModeData>) => void;\r\n resetMode: () => void;\r\n // Calculator control\r\n calculatorOpen: boolean;\r\n setCalculatorOpen: (open: boolean) => void;\r\n isHidden: boolean;\r\n setIsHidden: React.Dispatch<React.SetStateAction<boolean>>;\r\n // Modal-aware Brady AI\r\n hideBradyForModal: () => void;\r\n restoreBradyAfterModal: () => void;\r\n}\r\n\r\nconst BradyChatContext = createContext<BradyChatContextType | undefined>(undefined);\r\n\r\nconst initialMessages: ChatMessage[] = [\r\n {\r\n type: 'brady',\r\n text: \"introduce\",\r\n },\r\n];\r\n\r\nexport function BradyChatProvider({ children }: { children: ReactNode }) {\r\n const [workflowType, setWorkflowType] = useState<ChatWorkflowType>('free');\r\n const [messages, setMessages] = useState<ChatMessage[]>(initialMessages);\r\n // Mode system state\r\n const [activeMode, setActiveMode] = useState<ModeType>('none');\r\n const [modeStep, setModeStep] = useState<ModeStep>('initial');\r\n const [modeData, setModeData] = useState<ModeData>({});\r\n const [calculatorOpen, setCalculatorOpen] = useState(false);\r\n // Global hide/show state for Brady chat (default hidden)\r\n const [isHidden, setIsHidden] = useState(true);\r\n // Track previous visibility for modal\r\n const [wasBradyVisibleBeforeModal, setWasBradyVisibleBeforeModal] = useState(false);\r\n\r\n // Modal-aware hide/show\r\n const hideBradyForModal = () => {\r\n setWasBradyVisibleBeforeModal(!isHidden);\r\n setIsHidden(true);\r\n };\r\n const restoreBradyAfterModal = () => {\r\n if (wasBradyVisibleBeforeModal) setIsHidden(false);\r\n };\r\n\r\n const startWorkflow = (workflow: ChatWorkflowType) => {\r\n setWorkflowType(workflow);\r\n\r\n // Set appropriate initial message based on workflow\r\n if (workflow === 'info-request') {\r\n setMessages([\r\n {\r\n type: 'brady',\r\n text: \"Happy to send you a personalized overview.\\n\\nIf you share your contact details below, we'll email you more information about AFN and how it could fit your goals.\",\r\n },\r\n ]);\r\n } else if (workflow === 'leadership-call') {\r\n setMessages([\r\n {\r\n type: 'brady',\r\n text: \"Happy to connect you with AFN leadership.\\n\\nShare your details below and we'll have someone reach out shortly.\\nIf you'd like, you can also suggest a good time to talk.\",\r\n },\r\n ]);\r\n } else if (workflow === 'personalized-overview-request') {\r\n setMessages([\r\n {\r\n type: 'brady',\r\n text: \"I'll help you get a personalized dashboard and earnings calculator.\\n\\nShare your details below and we'll create a custom overview showing exactly what your business could look like at AFN.\",\r\n },\r\n ]);\r\n } else {\r\n setMessages(initialMessages);\r\n }\r\n };\r\n\r\n const addMessage = (message: ChatMessage) => {\r\n setMessages((prev) => [...prev, message]);\r\n };\r\n\r\n const setWorkflow = (workflow: ChatWorkflowType) => {\r\n setWorkflowType(workflow);\r\n };\r\n\r\n const resetChat = () => {\r\n setWorkflowType('free');\r\n setMessages(initialMessages);\r\n resetMode();\r\n };\r\n\r\n // Mode system functions\r\n const activateMode = (mode: ModeType) => {\r\n setActiveMode(mode);\r\n setModeStep('initial');\r\n setModeData({});\r\n\r\n // Set initial mode message\r\n if (mode === 'earnings') {\r\n setMessages([\r\n {\r\n type: 'brady',\r\n text: \"Earnings Mode is on.\\n\\nI'll focus on how volume, efficiency, and time savings can impact your income.\",\r\n },\r\n ]);\r\n setModeStep('volume');\r\n } else if (mode === 'profit') {\r\n setMessages([\r\n {\r\n type: 'brady',\r\n text: 'Profit Mode is on.\\n\\nI\\'ll focus on branch economics—volume, margin, expenses, and profitability.',\r\n },\r\n ]);\r\n setModeStep('volume');\r\n }\r\n };\r\n\r\n const updateModeData = (data: Partial<ModeData>) => {\r\n setModeData((prev) => ({ ...prev, ...data }));\r\n };\r\n\r\n const resetMode = () => {\r\n setActiveMode('none');\r\n setModeStep('initial');\r\n setModeData({});\r\n setCalculatorOpen(false);\r\n };\r\n\r\n return (\r\n <BradyChatContext.Provider\r\n value={{\r\n workflowType,\r\n messages,\r\n startWorkflow,\r\n addMessage,\r\n setWorkflow,\r\n resetChat,\r\n activeMode,\r\n modeStep,\r\n modeData,\r\n activateMode,\r\n setModeStep,\r\n updateModeData,\r\n resetMode,\r\n calculatorOpen,\r\n setCalculatorOpen,\r\n isHidden,\r\n setIsHidden,\r\n hideBradyForModal,\r\n restoreBradyAfterModal,\r\n }}\r\n >\r\n {children}\r\n </BradyChatContext.Provider>\r\n );\r\n}\r\n\r\nexport function useBradyChat() {\r\n const context = useContext(BradyChatContext);\r\n if (context === undefined) {\r\n throw new Error('useBradyChat must be used within a BradyChatProvider');\r\n }\r\n return context;\r\n}\r\n\r\n","'use client';\r\n\r\nimport { useState, useRef, useEffect } from 'react';\r\nimport { motion, AnimatePresence } from 'motion/react';\r\nimport { Send, Mic } from 'lucide-react';\r\n\r\nimport { checkBradyHealth } from './api/bradyHealth';\r\nimport { sendBradyPrompt } from './api/afnBradyApi';\r\nimport { useBradyChat } from './BradyChatContext';\r\nimport { InfoRequestForm } from './InfoRequestForm';\r\nimport { LeadershipCallForm } from './LeadershipCallForm';\r\nimport { PersonalizedOverviewForm } from './PersonalizedOverviewForm';\r\nimport { QuickSuggestions } from './QuickSuggestions';\r\nimport { ModePromptTree } from './ModePromptTree';\r\nimport { ImageWithFallback } from './ImageWithFallback';\r\n\r\ntype ModeVariant = 'loan-officer' | 'branch-manager';\r\n\r\nexport interface EnhancedBradyChatProps {\r\n /**\r\n * Controls whether the mode toggle uses Earnings (LO) or Profit (branch manager) language.\r\n * Defaults to 'loan-officer'.\r\n */\r\n modeVariant?: ModeVariant;\r\n /**\r\n * Avatar image URL for Brady.\r\n * Typically you pass something like `/bradyIcon.png` from your app's public assets.\r\n */\r\n avatarSrc: string;\r\n}\r\n\r\nexport function EnhancedBradyChat({ modeVariant = 'loan-officer', avatarSrc }: EnhancedBradyChatProps) {\r\n const [bradyHealthy, setBradyHealthy] = useState(true);\r\n const {\r\n workflowType,\r\n messages,\r\n addMessage,\r\n resetChat,\r\n setWorkflow,\r\n activeMode,\r\n modeStep,\r\n modeData,\r\n setModeStep,\r\n updateModeData,\r\n setCalculatorOpen,\r\n activateMode,\r\n resetMode,\r\n isHidden,\r\n setIsHidden,\r\n } = useBradyChat();\r\n const [inputValue, setInputValue] = useState('');\r\n const [showForm, setShowForm] = useState(false);\r\n const [inputDisabled, setInputDisabled] = useState(false);\r\n const [showModePrompts, setShowModePrompts] = useState(false);\r\n const messagesEndRef = useRef<HTMLDivElement>(null);\r\n const [suggestionLinks, setSuggestionLinks] = useState<{ text: string; prompt: string }[] | null>(null);\r\n\r\n const isBranchManager = modeVariant === 'branch-manager';\r\n const pageMode = isBranchManager ? 'profit' : 'earnings';\r\n const isModeActive = activeMode === pageMode;\r\n const hasPersonalizedData = false;\r\n\r\n const handleFocusToggle = () => {\r\n if (isModeActive) {\r\n resetMode();\r\n } else {\r\n activateMode(pageMode);\r\n setTimeout(() => {\r\n addMessage({\r\n type: 'brady',\r\n text: `${\r\n isBranchManager ? 'Profit' : 'Earnings'\r\n } Mode is on.\\n\\nI'll focus on ways to increase ${\r\n isBranchManager ? 'profit' : 'income'\r\n } using ${\r\n isBranchManager\r\n ? 'branch economics, recruiting leverage, and operational efficiency'\r\n : 'volume, efficiency, and time savings'\r\n }.`,\r\n });\r\n }, 300);\r\n }\r\n };\r\n\r\n useEffect(() => {\r\n let mounted = true;\r\n const checkHealth = async () => {\r\n const healthy = await checkBradyHealth();\r\n if (mounted) setBradyHealthy(healthy);\r\n };\r\n checkHealth();\r\n const interval = setInterval(checkHealth, 60000);\r\n return () => {\r\n mounted = false;\r\n clearInterval(interval);\r\n };\r\n }, []);\r\n\r\n useEffect(() => {\r\n if (\r\n workflowType === 'info-request' ||\r\n workflowType === 'leadership-call' ||\r\n workflowType === 'personalized-overview-request'\r\n ) {\r\n setShowForm(true);\r\n setInputDisabled(true);\r\n setShowModePrompts(false);\r\n } else {\r\n setShowForm(false);\r\n setInputDisabled(false);\r\n }\r\n }, [workflowType]);\r\n\r\n useEffect(() => {\r\n if (activeMode !== 'none' && modeStep === 'volume') {\r\n setShowModePrompts(true);\r\n\r\n if (activeMode === 'earnings') {\r\n if (hasPersonalizedData) {\r\n setTimeout(() => {\r\n addMessage({\r\n type: 'brady',\r\n text: 'I have an estimate of your recent production.\\nDoes this feel close?',\r\n });\r\n }, 500);\r\n } else {\r\n setTimeout(() => {\r\n addMessage({\r\n type: 'brady',\r\n text: 'To keep this realistic, about how much volume do you fund in an average month?',\r\n });\r\n }, 500);\r\n }\r\n } else if (activeMode === 'profit') {\r\n if (hasPersonalizedData) {\r\n setTimeout(() => {\r\n addMessage({\r\n type: 'brady',\r\n text: 'I have a baseline view of your branch.\\nDoes this feel directionally right?',\r\n });\r\n }, 500);\r\n } else {\r\n setTimeout(() => {\r\n addMessage({\r\n type: 'brady',\r\n text: 'To start, about how much volume does your branch fund annually?',\r\n });\r\n }, 500);\r\n }\r\n }\r\n }\r\n }, [activeMode, modeStep, addMessage]);\r\n\r\n useEffect(() => {\r\n scrollToBottom();\r\n }, [messages, showForm, showModePrompts]);\r\n\r\n const scrollToBottom = () => {\r\n messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });\r\n };\r\n\r\n const handleModeResponse = (response: string, data?: any) => {\r\n addMessage({ type: 'user', text: response });\r\n setShowModePrompts(false);\r\n\r\n if (data) {\r\n updateModeData(data);\r\n }\r\n\r\n if (activeMode === 'earnings') {\r\n if (modeStep === 'volume') {\r\n setTimeout(() => {\r\n addMessage({\r\n type: 'brady',\r\n text: 'And roughly how do you get paid today?',\r\n });\r\n setModeStep('comp');\r\n setShowModePrompts(true);\r\n }, 800);\r\n } else if (modeStep === 'comp') {\r\n setTimeout(() => {\r\n addMessage({\r\n type: 'brady',\r\n text: \"Got it. I'll pull this together so you can see it clearly.\",\r\n });\r\n setModeStep('calculator');\r\n setTimeout(() => {\r\n setCalculatorOpen(true);\r\n setModeStep('complete');\r\n setTimeout(() => {\r\n addMessage({\r\n type: 'brady',\r\n text: 'Want to sanity-check these assumptions together?',\r\n });\r\n setShowModePrompts(true);\r\n }, 1000);\r\n }, 800);\r\n }, 800);\r\n } else if (modeStep === 'complete') {\r\n if (response.includes('Talk through')) {\r\n setShowModePrompts(false);\r\n setTimeout(() => {\r\n startWorkflow('leadership-call');\r\n }, 500);\r\n } else if (response.includes('Adjust')) {\r\n setShowModePrompts(false);\r\n setTimeout(() => {\r\n setCalculatorOpen(true);\r\n }, 500);\r\n } else {\r\n setShowModePrompts(false);\r\n setTimeout(() => {\r\n addMessage({\r\n type: 'brady',\r\n text: \"I'm here whenever you need me. What else would you like to explore?\",\r\n });\r\n }, 800);\r\n }\r\n }\r\n } else if (activeMode === 'profit') {\r\n if (modeStep === 'volume') {\r\n setTimeout(() => {\r\n addMessage({\r\n type: 'brady',\r\n text:\r\n \"For modeling, I'll assume:\\n• ~300 bps branch margin\\n• ~150 bps gross profit\\n\" +\r\n '• ~75 bps operating expenses\\n\\nWe can adjust all of this.',\r\n });\r\n setModeStep('economics');\r\n setShowModePrompts(true);\r\n }, 800);\r\n } else if (modeStep === 'economics') {\r\n setTimeout(() => {\r\n addMessage({\r\n type: 'brady',\r\n text: \"Here's a clean P&L view based on what we discussed.\",\r\n });\r\n setModeStep('calculator');\r\n setTimeout(() => {\r\n setCalculatorOpen(true);\r\n setModeStep('complete');\r\n setTimeout(() => {\r\n addMessage({\r\n type: 'brady',\r\n text: \"Want help building a realistic pro forma based on AFN's structure?\",\r\n });\r\n setShowModePrompts(true);\r\n }, 1000);\r\n }, 800);\r\n }, 800);\r\n } else if (modeStep === 'complete') {\r\n if (response.includes('Sanity-check') || response.includes('leadership')) {\r\n setShowModePrompts(false);\r\n setTimeout(() => {\r\n startWorkflow('leadership-call');\r\n }, 500);\r\n } else if (response.includes('Adjust')) {\r\n setShowModePrompts(false);\r\n setTimeout(() => {\r\n setCalculatorOpen(true);\r\n }, 500);\r\n }\r\n }\r\n }\r\n };\r\n\r\n const handleSend = async () => {\r\n if (inputValue.trim() && !inputDisabled) {\r\n const userText = inputValue;\r\n addMessage({ type: 'user', text: userText });\r\n setInputValue('');\r\n try {\r\n const apiResponse = await sendBradyPrompt([{ role: 'user', content: userText }]);\r\n let mappedType: 'user' | 'brady' | 'form' = 'brady';\r\n if (apiResponse.role === 'user') mappedType = 'user';\r\n addMessage({ type: mappedType, text: apiResponse.content });\r\n } catch {\r\n addMessage({ type: 'brady', text: 'Sorry, Brady AI is currently unavailable.' });\r\n }\r\n }\r\n };\r\n\r\n const handleQuickSuggestion = async (text: string) => {\r\n addMessage({ type: 'user', text });\r\n try {\r\n const apiResponse = await sendBradyPrompt([{ role: 'user', content: text }]);\r\n\r\n if (Array.isArray(apiResponse.suggestionLink)) {\r\n setSuggestionLinks(apiResponse.suggestionLink);\r\n }\r\n\r\n let mappedType: 'user' | 'brady' | 'form' = 'brady';\r\n if (apiResponse.role === 'user') mappedType = 'user';\r\n addMessage({ type: mappedType, text: apiResponse.content });\r\n } catch {\r\n addMessage({ type: 'brady', text: 'Sorry, Brady AI is currently unavailable.' });\r\n }\r\n };\r\n\r\n const handleInfoFormSubmit = (data: any) => {\r\n addMessage({\r\n type: 'brady',\r\n text:\r\n \"Got it — thanks.\\n\\nWe'll email you a personalized overview shortly.\\nIf you have questions in the meantime, I'm here to help.\",\r\n });\r\n setShowForm(false);\r\n setInputDisabled(false);\r\n setWorkflow('free');\r\n };\r\n\r\n const handleLeadershipFormSubmit = (data: any) => {\r\n addMessage({\r\n type: 'brady',\r\n text:\r\n \"Thanks — you're all set.\\n\\nSomeone from AFN leadership will reach out shortly to connect.\\nIn the meantime, feel free to ask me anything.\",\r\n });\r\n setShowForm(false);\r\n setInputDisabled(false);\r\n setWorkflow('free');\r\n };\r\n\r\n const handlePersonalizedOverviewFormSubmit = (data: any) => {\r\n addMessage({\r\n type: 'brady',\r\n text:\r\n \"Perfect — thanks!\\n\\nWe'll create a personalized dashboard and earnings calculator based on your information and send it to you shortly.\\n\\nYou'll be able to see exactly what your business could look like at AFN with specific projections tailored to your situation.\",\r\n });\r\n setShowForm(false);\r\n setInputDisabled(false);\r\n setWorkflow('free');\r\n };\r\n\r\n const handleFormCancel = () => {\r\n setShowForm(false);\r\n setInputDisabled(false);\r\n resetChat();\r\n };\r\n\r\n const buildSuggestions = () => {\r\n if (suggestionLinks && suggestionLinks.length > 0) {\r\n return suggestionLinks.map((s) => ({\r\n text: s.text,\r\n action: () => handleQuickSuggestion(s.prompt),\r\n }));\r\n }\r\n return [\r\n {\r\n text: 'How does AFN help LOs grow?',\r\n action: () => handleQuickSuggestion('How does AFN help LOs grow?'),\r\n },\r\n {\r\n text: 'How does AFN help branch managers earn more?',\r\n action: () => handleQuickSuggestion('How does AFN help branch managers earn more?'),\r\n },\r\n {\r\n text: 'Why do people choose AFN?',\r\n action: () => handleQuickSuggestion('Why do people choose AFN?'),\r\n },\r\n {\r\n text: 'The AFN Advantage',\r\n action: () => handleQuickSuggestion('See How AFN Supports Loan Officer Success'),\r\n },\r\n {\r\n text: 'Why AFN?',\r\n action: () => handleQuickSuggestion('Why AFN?'),\r\n },\r\n {\r\n text: 'How does AI help me earn more?',\r\n action: () => handleQuickSuggestion('How does AI help me earn more?'),\r\n },\r\n {\r\n text: 'What makes AFN different?',\r\n action: () => handleQuickSuggestion('What makes AFN different?'),\r\n },\r\n ];\r\n };\r\n\r\n const initialSuggestions = buildSuggestions();\r\n const postSubmitSuggestions = buildSuggestions();\r\n\r\n const showPostSubmitSuggestions = messages.length > 2 && !showForm && workflowType === 'free' && activeMode === 'none';\r\n\r\n const startWorkflow = (workflow: any) => {\r\n setWorkflow(workflow);\r\n if (workflow === 'info-request') {\r\n setShowForm(true);\r\n setInputDisabled(true);\r\n } else if (workflow === 'leadership-call') {\r\n setShowForm(true);\r\n setInputDisabled(true);\r\n }\r\n };\r\n\r\n const modeBadge =\r\n activeMode !== 'none' ? (\r\n <div\r\n className={`px-3 py-1 rounded-full text-xs font-medium ${\r\n activeMode === 'earnings'\r\n ? 'bg-[#8B5CF6]/20 text-[#8B5CF6] border border-[#8B5CF6]/30'\r\n : 'bg-[#4399D1]/20 text-[#4399D1] border border-[#4399D1]/30'\r\n }`}\r\n >\r\n {activeMode === 'earnings' ? 'Earnings Mode' : 'Profit Mode'}\r\n </div>\r\n ) : null;\r\n\r\n if (isHidden) return null;\r\n if (!bradyHealthy) {\r\n return (\r\n <div className=\"fixed top-0 right-0 w-full md:w-[360px] h-screen flex flex-col bg-gradient-to-br dark:from-zinc-900 dark:to-zinc-800 from-white to-zinc-50 border-l md:border-l dark:border-zinc-700 border-zinc-300 shadow-2xl z-[100] overflow-hidden transition-all duration-300 items-center justify-center\">\r\n <div className=\"text-center text-zinc-500 dark:text-zinc-400 text-lg font-medium\">\r\n Sorry, Brady AI is currently unavailable.\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className=\"fixed top-0 right-0 w-full md:w-[360px] h-screen flex flex-col bg-gradient-to-br dark:from-zinc-900 dark:to-zinc-800 from-white to-zinc-50 border-l md:border-l dark:border-zinc-700 border-zinc-300 shadow-2xl z-[100] overflow-hidden transition-all duration-300\">\r\n <div className=\"flex items-center justify-between px-4 py-3 border-b dark:border-zinc-800 border-zinc-200 dark:bg-zinc-950/80 bg-white/95 backdrop-blur-lg\">\r\n <div className=\"flex items-center gap-3\">\r\n <div className=\"relative\">\r\n <span className=\"relative w-10 h-10 block group\">\r\n <span\r\n className={`absolute inset-0 rounded-full transition-colors duration-300 ${\r\n bradyHealthy ? 'dark:bg-zinc-700/40 bg-transparent' : 'bg-red-600/80 dark:bg-red-700/80'\r\n }`}\r\n ></span>\r\n <ImageWithFallback\r\n src={avatarSrc}\r\n alt=\"Brady AI\"\r\n className=\"w-10 h-10 relative z-10\"\r\n onClick={() => setIsHidden(true)}\r\n />\r\n </span>\r\n </div>\r\n <div className=\"dark:text-white text-zinc-900\">Brady AI</div>\r\n </div>\r\n\r\n <div className=\"relative inline-flex items-center h-[34px] w-[150px] dark:bg-zinc-800/50 bg-zinc-200 rounded-full p-1\">\r\n <button\r\n onClick={() => isModeActive && resetMode()}\r\n className={`relative z-10 flex-1 h-full rounded-full text-[11px] tracking-wide uppercase font-medium transition-all duration-300 flex items-center justify-center ${\r\n !isModeActive\r\n ? 'text-white'\r\n : 'dark:text-zinc-500 text-zinc-600 hover:dark:bg-zinc-700/50 hover:bg-zinc-300/50'\r\n }`}\r\n >\r\n NORMAL\r\n </button>\r\n\r\n <div className=\"relative flex-1\">\r\n {!isModeActive && (\r\n <div\r\n className=\"absolute inset-0 rounded-full animate-pulse\"\r\n style={{\r\n boxShadow: isBranchManager\r\n ? '0 0 16px rgba(67, 153, 209, 0.6), inset 0 0 10px rgba(67, 153, 209, 0.3)'\r\n : '0 0 16px rgba(139, 92, 246, 0.6), inset 0 0 10px rgba(139, 92, 246, 0.3)',\r\n animation: 'pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite',\r\n }}\r\n />\r\n )}\r\n <button\r\n onClick={() => !isModeActive && handleFocusToggle()}\r\n className={`relative z-10 w-full h-full rounded-full text-[11px] tracking-wide uppercase font-medium transition-all duration-300 flex items-center justify-center ${\r\n isModeActive\r\n ? 'text-white'\r\n : 'dark:text-zinc-500 text-zinc-600 hover:dark:bg-zinc-700/50 hover:bg-zinc-300/50'\r\n }`}\r\n >\r\n {isBranchManager ? 'PROFIT' : 'EARNINGS'}\r\n </button>\r\n </div>\r\n\r\n <div\r\n className={`absolute top-1 bottom-1 rounded-full transition-all duration-300 ${\r\n isModeActive ? 'left-[50%] right-1' : 'left-1 right-[50%]'\r\n }`}\r\n style={\r\n isModeActive\r\n ? {\r\n background: isBranchManager\r\n ? 'linear-gradient(135deg, #4399D1 0%, #3b82d9 100%)'\r\n : 'linear-gradient(135deg, #8B5CF6 0%, #7C3AED 100%)',\r\n boxShadow: isBranchManager\r\n ? '0 0 16px rgba(67, 153, 209, 0.15)'\r\n : '0 0 16px rgba(139, 92, 246, 0.15)',\r\n }\r\n : {\r\n background: 'var(--tw-gradient-stops)',\r\n backgroundImage: 'linear-gradient(135deg, rgb(82, 82, 91) 0%, rgb(63, 63, 70) 100%)',\r\n }\r\n }\r\n />\r\n </div>\r\n </div>\r\n\r\n {modeBadge && (\r\n <div className=\"px-4 py-2 border-b dark:border-zinc-800 border-zinc-200\">\r\n {modeBadge}\r\n </div>\r\n )}\r\n\r\n <div className=\"flex-1 overflow-y-auto p-4 space-y-4\">\r\n <AnimatePresence>\r\n {messages.map((msg, idx) => (\r\n <motion.div\r\n key={idx}\r\n initial={{ opacity: 0, y: 10 }}\r\n animate={{ opacity: 1, y: 0 }}\r\n className={`flex ${msg.type === 'user' ? 'justify-end' : 'justify-start'}`}\r\n >\r\n <div\r\n className={`px-4 py-3 rounded-2xl whitespace-pre-line ${\r\n msg.type === 'user'\r\n ? 'bg-[#8B5CF6] text-white rounded-br-sm'\r\n : 'dark:bg-zinc-800 bg-zinc-100 dark:text-zinc-100 text-zinc-900 rounded-bl-sm'\r\n }`}\r\n >\r\n {msg.text}\r\n </div>\r\n </motion.div>\r\n ))}\r\n </AnimatePresence>\r\n\r\n {showForm && workflowType === 'info-request' && (\r\n <InfoRequestForm onSubmit={handleInfoFormSubmit} onCancel={handleFormCancel} />\r\n )}\r\n\r\n {showForm && workflowType === 'leadership-call' && (\r\n <LeadershipCallForm onSubmit={handleLeadershipFormSubmit} onCancel={handleFormCancel} />\r\n )}\r\n\r\n {showForm && workflowType === 'personalized-overview-request' && (\r\n <PersonalizedOverviewForm\r\n onSubmit={handlePersonalizedOverviewFormSubmit}\r\n onCancel={handleFormCancel}\r\n />\r\n )}\r\n\r\n {showModePrompts && activeMode !== 'none' && (\r\n <ModePromptTree\r\n mode={activeMode as 'earnings' | 'profit'}\r\n step={modeStep}\r\n hasPersonalizedData={hasPersonalizedData}\r\n onResponse={handleModeResponse}\r\n />\r\n )}\r\n\r\n {!showForm &&\r\n !showModePrompts &&\r\n messages.length === 1 &&\r\n workflowType === 'free' &&\r\n activeMode === 'none' && <QuickSuggestions suggestions={initialSuggestions} />}\r\n\r\n {showPostSubmitSuggestions && !showModePrompts && (\r\n <QuickSuggestions suggestions={postSubmitSuggestions} />\r\n )}\r\n\r\n <div ref={messagesEndRef} />\r\n </div>\r\n\r\n <div className=\"p-4 border-t dark:border-zinc-800 border-zinc-200 dark:bg-zinc-900 bg-zinc-50\">\r\n <div\r\n className={`flex items-center gap-2 dark:bg-zinc-800 bg-white rounded-full px-4 py-3 border dark:border-zinc-700 border-zinc-300 focus-within:border-[#8B5CF6] transition-colors ${\r\n inputDisabled || showModePrompts ? 'opacity-50 cursor-not-allowed' : ''\r\n }`}\r\n >\r\n <input\r\n type=\"text\"\r\n value={inputValue}\r\n onChange={(e) => setInputValue(e.target.value)}\r\n onKeyPress={(e) => e.key === 'Enter' && handleSend()}\r\n placeholder={\r\n inputDisabled || showModePrompts ? 'Use buttons above...' : 'Ask me anything...'\r\n }\r\n disabled={inputDisabled || showModePrompts}\r\n className=\"flex-1 bg-transparent dark:text-white text-zinc-900 dark:placeholder-zinc-500 placeholder-zinc-400 outline-none text-sm disabled:cursor-not-allowed\"\r\n />\r\n <button\r\n className=\"dark:text-zinc-400 text-zinc-500 dark:hover:text-white hover:text-zinc-900 transition-colors disabled:opacity-50\"\r\n disabled={inputDisabled || showModePrompts}\r\n >\r\n <Mic className=\"w-5 h-5\" />\r\n </button>\r\n <button\r\n onClick={handleSend}\r\n disabled={inputDisabled || showModePrompts}\r\n className=\"bg-[#8B5CF6] hover:bg-[#7C3AED] text-white rounded-full p-2 transition-colors disabled:opacity-50 disabled:cursor-not-allowed\"\r\n >\r\n <Send className=\"w-4 h-4\" />\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\n","// afnBradyApi.ts (library version)\r\n// Utility for integrating with AFN Brady Jr API\r\n\r\n// Use environment variable for API key\r\n// Supports both server (BRADY_API_KEY, BRADY_API_URL) and browser (NEXT_PUBLIC_BRADY_API_KEY, NEXT_PUBLIC_BRADY_API_URL)\r\n// Consumers: Set NEXT_PUBLIC_BRADY_API_KEY and NEXT_PUBLIC_BRADY_API_URL in your app's .env.local for browser use\r\nexport const DEFAULT_BRADY_API_KEY =\r\n typeof process !== 'undefined' && process.env && (\r\n process.env.BRADY_API_KEY || process.env.NEXT_PUBLIC_BRADY_API_KEY\r\n )\r\n ? process.env.BRADY_API_KEY || process.env.NEXT_PUBLIC_BRADY_API_KEY\r\n : 'za2345DDDzXycXKHJvVj80TIsPgooB7iNbwcS9KLzoeaOljlXmJQQJ99BJAC4f1cMXJ3w3AAABACOGQzXz';\r\n\r\nexport const API_URL =\r\n typeof process !== 'undefined' && process.env && (\r\n process.env.BRADY_API_URL || process.env.NEXT_PUBLIC_BRADY_API_URL\r\n )\r\n ? process.env.BRADY_API_URL || process.env.NEXT_PUBLIC_BRADY_API_URL\r\n : 'https://afn-bradyjr-api-dev.azurewebsites.net/';\r\n\r\nexport interface BradyMessage {\r\n role: 'user' | 'assistant' | 'system';\r\n content: string;\r\n}\r\n\r\nexport interface BradyChatRequest {\r\n messages: BradyMessage[];\r\n}\r\n\r\nexport interface BradyChatResponse {\r\n role: string;\r\n type: string;\r\n content: string;\r\n suggestionLink?: { text: string; prompt: string }[];\r\n}\r\n\r\nexport async function sendBradyPrompt(\r\n messages: BradyMessage[],\r\n apiKey: string = DEFAULT_BRADY_API_KEY\r\n): Promise<BradyChatResponse> {\r\n\r\n console.log('[DEFAULT_BRADY_API_KEY]', DEFAULT_BRADY_API_KEY);\r\n console.log('[API_URL]', API_URL);\r\n\r\n const res = await fetch(`${API_URL}/api/chat/prompt`, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'X-API-KEY': apiKey\r\n },\r\n body: JSON.stringify({ messages })\r\n });\r\n if (!res.ok) throw new Error('Brady API error: ' + res.status);\r\n const data = await res.json();\r\n if (process.env.NODE_ENV === 'development') {\r\n // eslint-disable-next-line no-console\r\n console.log('[Brady API Response]', data);\r\n }\r\n return data;\r\n}\r\n\r\n","// bradyHealth.ts (library version)\r\n// Utility to check health of Brady AI API\r\n\r\nimport { API_URL } from './afnBradyApi';\r\n\r\nexport async function checkBradyHealth(): Promise<boolean> {\r\n try {\r\n const res = await fetch(`${API_URL}/api/Health`);\r\n if (!res.ok) return false;\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\n","'use client';\r\n\r\nimport React, { useState } from 'react';\r\nimport { motion } from 'motion/react';\r\n\r\ninterface InfoRequestFormProps {\r\n onSubmit: (data: { firstName: string; lastName: string; email: string; phone?: string }) => void;\r\n onCancel: () => void;\r\n}\r\n\r\nexport function InfoRequestForm({ onSubmit, onCancel }: InfoRequestFormProps) {\r\n const [formData, setFormData] = useState({\r\n firstName: '',\r\n lastName: '',\r\n email: '',\r\n phone: '',\r\n });\r\n const [errors, setErrors] = useState<Record<string, string>>({});\r\n\r\n const handleSubmit = (e: React.FormEvent) => {\r\n e.preventDefault();\r\n const newErrors: Record<string, string> = {};\r\n\r\n if (!formData.firstName.trim()) {\r\n newErrors.firstName = 'First name is required';\r\n }\r\n if (!formData.lastName.trim()) {\r\n newErrors.lastName = 'Last name is required';\r\n }\r\n if (!formData.email.trim()) {\r\n newErrors.email = 'Email is required';\r\n } else if (!/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(formData.email)) {\r\n newErrors.email = 'Please enter a valid email address';\r\n }\r\n\r\n if (Object.keys(newErrors).length > 0) {\r\n setErrors(newErrors);\r\n return;\r\n }\r\n\r\n onSubmit(formData);\r\n };\r\n\r\n return (\r\n <motion.div\r\n initial={{ opacity: 0, y: 10 }}\r\n animate={{ opacity: 1, y: 0 }}\r\n className=\"bg-gradient-to-br from-white to-zinc-50 dark:from-zinc-800 dark:to-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-2xl p-6 max-h-[360px]\"\r\n >\r\n <h3 className=\"text-lg text-zinc-900 dark:text-white mb-4\">Send Me More Information</h3>\r\n\r\n <form onSubmit={handleSubmit} className=\"space-y-3\">\r\n <div>\r\n <input\r\n type=\"text\"\r\n placeholder=\"First Name\"\r\n value={formData.firstName}\r\n onChange={(e) => setFormData({ ...formData, firstName: e.target.value })}\r\n className=\"w-full px-4 py-2.5 bg-white dark:bg-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-lg text-zinc-900 dark:text-white placeholder-zinc-500 focus:border-[#8B5CF6] focus:outline-none transition-colors\"\r\n />\r\n {errors.firstName && <p className=\"text-red-500 text-xs mt-1\">{errors.firstName}</p>}\r\n </div>\r\n\r\n <div>\r\n <input\r\n type=\"text\"\r\n placeholder=\"Last Name\"\r\n value={formData.lastName}\r\n onChange={(e) => setFormData({ ...formData, lastName: e.target.value })}\r\n className=\"w-full px-4 py-2.5 bg-white dark:bg-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-lg text-zinc-900 dark:text-white placeholder-zinc-500 focus:border-[#8B5CF6] focus:outline-none transition-colors\"\r\n />\r\n {errors.lastName && <p className=\"text-red-500 text-xs mt-1\">{errors.lastName}</p>}\r\n </div>\r\n\r\n <div>\r\n <input\r\n type=\"email\"\r\n placeholder=\"Email Address\"\r\n value={formData.email}\r\n onChange={(e) => setFormData({ ...formData, email: e.target.value })}\r\n className=\"w-full px-4 py-2.5 bg-white dark:bg-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-lg text-zinc-900 dark:text-white placeholder-zinc-500 focus:border-[#8B5CF6] focus:outline-none transition-colors\"\r\n />\r\n {errors.email && <p className=\"text-red-500 text-xs mt-1\">{errors.email}</p>}\r\n </div>\r\n\r\n <div>\r\n <input\r\n type=\"tel\"\r\n placeholder=\"Phone (optional)\"\r\n value={formData.phone}\r\n onChange={(e) => setFormData({ ...formData, phone: e.target.value })}\r\n className=\"w-full px-4 py-2.5 bg-white dark:bg-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-lg text-zinc-900 dark:text-white placeholder-zinc-500 focus:border-[#8B5CF6] focus:outline-none transition-colors\"\r\n />\r\n </div>\r\n\r\n <div className=\"flex gap-2 pt-2\">\r\n <button\r\n type=\"submit\"\r\n className=\"flex-1 bg-[#8B5CF6] hover:bg-[#7C3AED] text-white py-2.5 rounded-lg transition-colors\"\r\n >\r\n Send Information\r\n </button>\r\n <button\r\n type=\"button\"\r\n onClick={onCancel}\r\n className=\"px-4 text-zinc-600 dark:text-zinc-400 hover:text-zinc-900 dark:hover:text-white transition-colors\"\r\n >\r\n Cancel\r\n </button>\r\n </div>\r\n </form>\r\n </motion.div>\r\n );\r\n}\r\n\r\n","'use client';\r\n\r\nimport React, { useState } from 'react';\r\nimport { motion } from 'motion/react';\r\nimport { Calendar, Clock } from 'lucide-react';\r\n\r\ninterface LeadershipCallFormProps {\r\n onSubmit: (data: {\r\n firstName: string;\r\n lastName: string;\r\n email: string;\r\n phone: string;\r\n preferredDate?: string;\r\n preferredTime?: string;\r\n }) => void;\r\n onCancel: () => void;\r\n}\r\n\r\nexport function LeadershipCallForm({ onSubmit, onCancel }: LeadershipCallFormProps) {\r\n const [formData, setFormData] = useState({\r\n firstName: '',\r\n lastName: '',\r\n email: '',\r\n phone: '',\r\n preferredDate: '',\r\n preferredTime: '',\r\n });\r\n const [errors, setErrors] = useState<Record<string, string>>({});\r\n\r\n const handleSubmit = (e: React.FormEvent) => {\r\n e.preventDefault();\r\n const newErrors: Record<string, string> = {};\r\n\r\n if (!formData.firstName.trim()) {\r\n newErrors.firstName = 'First name is required';\r\n }\r\n if (!formData.lastName.trim()) {\r\n newErrors.lastName = 'Last name is required';\r\n }\r\n if (!formData.email.trim()) {\r\n newErrors.email = 'Email is required';\r\n } else if (!/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(formData.email)) {\r\n newErrors.email = 'Please enter a valid email address';\r\n }\r\n if (!formData.phone.trim()) {\r\n newErrors.phone = 'Phone number is required';\r\n }\r\n\r\n if (Object.keys(newErrors).length > 0) {\r\n setErrors(newErrors);\r\n return;\r\n }\r\n\r\n onSubmit(formData);\r\n };\r\n\r\n const timeSlots = ['Morning (8am - 12pm)', 'Afternoon (12pm - 5pm)', 'Evening (5pm - 8pm)'];\r\n\r\n return (\r\n <motion.div\r\n initial={{ opacity: 0, y: 10 }}\r\n animate={{ opacity: 1, y: 0 }}\r\n className=\"bg-gradient-to-br from-white to-zinc-50 dark:from-zinc-800 dark:to-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-2xl p-6\"\r\n >\r\n <h3 className=\"text-lg text-zinc-900 dark:text-white mb-4\">Talk to AFN Leadership</h3>\r\n\r\n <form onSubmit={handleSubmit} className=\"space-y-3\">\r\n <div>\r\n <input\r\n type=\"text\"\r\n placeholder=\"First Name\"\r\n value={formData.firstName}\r\n onChange={(e) => setFormData({ ...formData, firstName: e.target.value })}\r\n className=\"w-full px-4 py-2.5 bg-white dark:bg-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-lg text-zinc-900 dark:text-white placeholder-zinc-500 focus:border-[#8B5CF6] focus:outline-none transition-colors\"\r\n />\r\n {errors.firstName && <p className=\"text-red-500 text-xs mt-1\">{errors.firstName}</p>}\r\n </div>\r\n\r\n <div>\r\n <input\r\n type=\"text\"\r\n placeholder=\"Last Name\"\r\n value={formData.lastName}\r\n onChange={(e) => setFormData({ ...formData, lastName: e.target.value })}\r\n className=\"w-full px-4 py-2.5 bg-white dark:bg-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-lg text-zinc-900 dark:text-white placeholder-zinc-500 focus:border-[#8B5CF6] focus:outline-none transition-colors\"\r\n />\r\n {errors.lastName && <p className=\"text-red-500 text-xs mt-1\">{errors.lastName}</p>}\r\n </div>\r\n\r\n <div>\r\n <input\r\n type=\"email\"\r\n placeholder=\"Email Address\"\r\n value={formData.email}\r\n onChange={(e) => setFormData({ ...formData, email: e.target.value })}\r\n className=\"w-full px-4 py-2.5 bg-white dark:bg-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-lg text-zinc-900 dark:text-white placeholder-zinc-500 focus:border-[#8B5CF6] focus:outline-none transition-colors\"\r\n />\r\n {errors.email && <p className=\"text-red-500 text-xs mt-1\">{errors.email}</p>}\r\n </div>\r\n\r\n <div>\r\n <input\r\n type=\"tel\"\r\n placeholder=\"Phone Number\"\r\n value={formData.phone}\r\n onChange={(e) => setFormData({ ...formData, phone: e.target.value })}\r\n className=\"w-full px-4 py-2.5 bg-white dark:bg-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-lg text-zinc-900 dark:text-white placeholder-zinc-500 focus:border-[#8B5CF6] focus:outline-none transition-colors\"\r\n />\r\n {errors.phone && <p className=\"text-red-500 text-xs mt-1\">{errors.phone}</p>}\r\n </div>\r\n\r\n <div className=\"pt-2 border-t border-zinc-200 dark:border-zinc-700\">\r\n <p className=\"text-sm text-zinc-600 dark:text-zinc-400 mb-2\">Preferred Call Time (optional)</p>\r\n <div className=\"grid grid-cols-2 gap-2\">\r\n <div className=\"relative\">\r\n <Calendar className=\"pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-zinc-500\" />\r\n <input\r\n type=\"date\"\r\n value={formData.preferredDate}\r\n onChange={(e) => setFormData({ ...formData, preferredDate: e.target.value })}\r\n className=\"w-full pl-12 pr-4 py-2.5 bg-white dark:bg-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-lg text-zinc-900 dark:text-white text-sm focus:border-[#8B5CF6] focus:outline-none transition-colors\"\r\n />\r\n </div>\r\n <div className=\"relative\">\r\n <Clock className=\"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-zinc-500\" />\r\n <select\r\n value={formData.preferredTime}\r\n onChange={(e) => setFormData({ ...formData, preferredTime: e.target.value })}\r\n className=\"w-full pl-10 pr-4 py-2.5 bg-white dark:bg-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-lg text-zinc-900 dark:text-white text-sm focus:border-[#8B5CF6] focus:outline-none transition-colors appearance-none\"\r\n >\r\n <option value=\"\">Select time</option>\r\n {timeSlots.map((slot) => (\r\n <option key={slot} value={slot}>\r\n {slot}\r\n </option>\r\n ))}\r\n </select>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div className=\"flex gap-2 pt-2\">\r\n <button\r\n type=\"submit\"\r\n className=\"flex-1 bg-[#8B5CF6] hover:bg-[#7C3AED] text-white py-2.5 rounded-lg transition-colors\"\r\n >\r\n Request Call\r\n </button>\r\n <button\r\n type=\"button\"\r\n onClick={onCancel}\r\n className=\"px-4 text-zinc-600 dark:text-zinc-400 hover:text-zinc-900 dark:hover:text-white transition-colors\"\r\n >\r\n Cancel\r\n </button>\r\n </div>\r\n </form>\r\n </motion.div>\r\n );\r\n}\r\n\r\n","'use client';\r\n\r\nimport React, { useState } from 'react';\r\nimport { motion } from 'motion/react';\r\n\r\ninterface PersonalizedOverviewFormProps {\r\n onSubmit: (data: {\r\n firstName: string;\r\n lastName: string;\r\n email: string;\r\n phone?: string;\r\n nmlsId?: string;\r\n }) => void;\r\n onCancel: () => void;\r\n}\r\n\r\nexport function PersonalizedOverviewForm({ onSubmit, onCancel }: PersonalizedOverviewFormProps) {\r\n const [formData, setFormData] = useState({\r\n firstName: '',\r\n lastName: '',\r\n email: '',\r\n phone: '',\r\n nmlsId: '',\r\n });\r\n const [errors, setErrors] = useState<Record<string, string>>({});\r\n\r\n const handleSubmit = (e: React.FormEvent) => {\r\n e.preventDefault();\r\n const newErrors: Record<string, string> = {};\r\n\r\n if (!formData.firstName.trim()) {\r\n newErrors.firstName = 'First name is required';\r\n }\r\n if (!formData.lastName.trim()) {\r\n newErrors.lastName = 'Last name is required';\r\n }\r\n if (!formData.email.trim()) {\r\n newErrors.email = 'Email is required';\r\n } else if (!/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(formData.email)) {\r\n newErrors.email = 'Please enter a valid email address';\r\n }\r\n\r\n if (Object.keys(newErrors).length > 0) {\r\n setErrors(newErrors);\r\n return;\r\n }\r\n\r\n onSubmit(formData);\r\n };\r\n\r\n return (\r\n <motion.div\r\n initial={{ opacity: 0, y: 10 }}\r\n animate={{ opacity: 1, y: 0 }}\r\n className=\"bg-gradient-to-br from-white to-zinc-50 dark:from-zinc-800 dark:to-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-2xl p-6\"\r\n >\r\n <h3 className=\"text-lg text-zinc-900 dark:text-white mb-4\">Request Personalized Overview</h3>\r\n\r\n <form onSubmit={handleSubmit} className=\"space-y-3\">\r\n <div>\r\n <input\r\n type=\"text\"\r\n placeholder=\"First Name\"\r\n value={formData.firstName}\r\n onChange={(e) => setFormData({ ...formData, firstName: e.target.value })}\r\n className=\"w-full px-4 py-2.5 bg-white dark:bg-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-lg text-zinc-900 dark:text-white placeholder-zinc-500 focus:border-[#8B5CF6] focus:outline-none transition-colors\"\r\n />\r\n {errors.firstName && <p className=\"text-red-500 text-xs mt-1\">{errors.firstName}</p>}\r\n </div>\r\n\r\n <div>\r\n <input\r\n type=\"text\"\r\n placeholder=\"Last Name\"\r\n value={formData.lastName}\r\n onChange={(e) => setFormData({ ...formData, lastName: e.target.value })}\r\n className=\"w-full px-4 py-2.5 bg-white dark:bg-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-lg text-zinc-900 dark:text-white placeholder-zinc-500 focus:border-[#8B5CF6] focus:outline-none transition-colors\"\r\n />\r\n {errors.lastName && <p className=\"text-red-500 text-xs mt-1\">{errors.lastName}</p>}\r\n </div>\r\n\r\n <div>\r\n <input\r\n type=\"email\"\r\n placeholder=\"Email Address\"\r\n value={formData.email}\r\n onChange={(e) => setFormData({ ...formData, email: e.target.value })}\r\n className=\"w-full px-4 py-2.5 bg-white dark:bg-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-lg text-zinc-900 dark:text-white placeholder-zinc-500 focus:border-[#8B5CF6] focus:outline-none transition-colors\"\r\n />\r\n {errors.email && <p className=\"text-red-500 text-xs mt-1\">{errors.email}</p>}\r\n </div>\r\n\r\n <div>\r\n <input\r\n type=\"tel\"\r\n placeholder=\"Phone (optional)\"\r\n value={formData.phone}\r\n onChange={(e) => setFormData({ ...formData, phone: e.target.value })}\r\n className=\"w-full px-4 py-2.5 bg-white dark:bg-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-lg text-zinc-900 dark:text-white placeholder-zinc-500 focus:border-[#8B5CF6] focus:outline-none transition-colors\"\r\n />\r\n </div>\r\n\r\n <div>\r\n <input\r\n type=\"text\"\r\n placeholder=\"NMLS ID (optional)\"\r\n value={formData.nmlsId}\r\n onChange={(e) => setFormData({ ...formData, nmlsId: e.target.value })}\r\n className=\"w-full px-4 py-2.5 bg-white dark:bg-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-lg text-zinc-900 dark:text-white placeholder-zinc-500 focus:border-[#8B5CF6] focus:outline-none transition-colors\"\r\n />\r\n </div>\r\n\r\n <div className=\"flex gap-2 pt-2\">\r\n <button\r\n type=\"submit\"\r\n className=\"flex-1 bg-[#8B5CF6] hover:bg-[#7C3AED] text-white py-2.5 rounded-lg transition-colors\"\r\n >\r\n Request Overview\r\n </button>\r\n <button\r\n type=\"button\"\r\n onClick={onCancel}\r\n className=\"px-4 text-zinc-600 dark:text-zinc-400 hover:text-zinc-900 dark:hover:text-white transition-colors\"\r\n >\r\n Cancel\r\n </button>\r\n </div>\r\n </form>\r\n </motion.div>\r\n );\r\n}\r\n\r\n","'use client';\r\n\r\nimport { motion } from 'motion/react';\r\n\r\ninterface QuickSuggestion {\r\n text: string;\r\n action: () => void;\r\n}\r\n\r\ninterface QuickSuggestionsProps {\r\n suggestions: QuickSuggestion[];\r\n}\r\n\r\nexport function QuickSuggestions({ suggestions }: QuickSuggestionsProps) {\r\n return (\r\n <motion.div\r\n initial={{ opacity: 0, y: 10 }}\r\n animate={{ opacity: 1, y: 0 }}\r\n className=\"flex flex-wrap gap-2\"\r\n >\r\n {suggestions.map((suggestion, idx) => (\r\n <button\r\n key={idx}\r\n onClick={suggestion.action}\r\n className=\"px-3 py-1.5 bg-zinc-100 dark:bg-zinc-800 hover:bg-zinc-200 dark:hover:bg-zinc-700 text-zinc-700 dark:text-zinc-300 text-sm rounded-full border border-zinc-300 dark:border-zinc-700 transition-colors\"\r\n >\r\n {suggestion.text}\r\n </button>\r\n ))}\r\n </motion.div>\r\n );\r\n}\r\n\r\n","'use client';\r\n\r\nimport { motion } from 'motion/react';\r\n\r\ninterface ModePromptTreeProps {\r\n mode: 'earnings' | 'profit';\r\n step: string;\r\n hasPersonalizedData: boolean;\r\n onResponse: (response: string, data?: any) => void;\r\n}\r\n\r\nexport function ModePromptTree({ mode, step, hasPersonalizedData, onResponse }: ModePromptTreeProps) {\r\n if (mode === 'earnings') {\r\n if (step === 'volume') {\r\n if (hasPersonalizedData) {\r\n return (\r\n <motion.div initial={{ opacity: 0, y: 10 }} animate={{ opacity: 1, y: 0 }} className=\"space-y-3\">\r\n <div className=\"grid grid-cols-1 gap-2\">\r\n <button\r\n onClick={() => onResponse('yes', { volumeMultiplier: 1.0 })}\r\n className=\"px-4 py-3 bg-[#8B5CF6] hover:bg-[#7C3AED] text-white rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Yes, that's about right\r\n </button>\r\n <button\r\n onClick={() => onResponse('higher', { volumeMultiplier: 1.1 })}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n It's a bit higher\r\n </button>\r\n <button\r\n onClick={() => onResponse('lower', { volumeMultiplier: 0.9 })}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n It's a bit lower\r\n </button>\r\n </div>\r\n </motion.div>\r\n );\r\n }\r\n\r\n return (\r\n <motion.div initial={{ opacity: 0, y: 10 }} animate={{ opacity: 1, y: 0 }} className=\"space-y-3\">\r\n <div className=\"grid grid-cols-1 gap-2\">\r\n <button\r\n onClick={() => onResponse('Under $500k', { volume: 400000 })}\r\n className=\"px-4 py-3 bg-[#8B5CF6] hover:bg-[#7C3AED] text-white rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Under $500k\r\n </button>\r\n <button\r\n onClick={() => onResponse('$500k – $1M', { volume: 750000 })}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n $500k – $1M\r\n </button>\r\n <button\r\n onClick={() => onResponse('$1M – $2M', { volume: 1500000 })}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n $1M – $2M\r\n </button>\r\n <button\r\n onClick={() => onResponse('$2M+', { volume: 2500000 })}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n $2M+\r\n </button>\r\n </div>\r\n </motion.div>\r\n );\r\n }\r\n\r\n if (step === 'comp') {\r\n return (\r\n <motion.div initial={{ opacity: 0, y: 10 }} animate={{ opacity: 1, y: 0 }} className=\"space-y-3\">\r\n <div className=\"grid grid-cols-1 gap-2\">\r\n <button\r\n onClick={() => onResponse('Under 100 bps', { comp: 0.95 })}\r\n className=\"px-4 py-3 bg-[#8B5CF6] hover:bg-[#7C3AED] text-white rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Under 100 bps\r\n </button>\r\n <button\r\n onClick={() => onResponse('Around 125 bps', { comp: 1.25 })}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Around 125 bps\r\n </button>\r\n <button\r\n onClick={() => onResponse('150+ bps', { comp: 1.5 })}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n 150+ bps\r\n </button>\r\n <button\r\n onClick={() => onResponse(\"I'm not sure\", { comp: 1.15 })}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n I'm not sure\r\n </button>\r\n </div>\r\n </motion.div>\r\n );\r\n }\r\n\r\n if (step === 'complete') {\r\n return (\r\n <motion.div initial={{ opacity: 0, y: 10 }} animate={{ opacity: 1, y: 0 }} className=\"space-y-3\">\r\n <div className=\"grid grid-cols-1 gap-2\">\r\n <button\r\n onClick={() => onResponse('Talk through this with AFN')}\r\n className=\"px-4 py-3 bg-[#8B5CF6] hover:bg-[#7C3AED] text-white rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Talk through this with AFN\r\n </button>\r\n <button\r\n onClick={() => onResponse('Adjust the numbers')}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Adjust the numbers\r\n </button>\r\n <button\r\n onClick={() => onResponse('Keep exploring')}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Keep exploring\r\n </button>\r\n </div>\r\n </motion.div>\r\n );\r\n }\r\n }\r\n\r\n if (mode === 'profit') {\r\n if (step === 'volume') {\r\n if (hasPersonalizedData) {\r\n return (\r\n <motion.div initial={{ opacity: 0, y: 10 }} animate={{ opacity: 1, y: 0 }} className=\"space-y-3\">\r\n <div className=\"grid grid-cols-1 gap-2\">\r\n <button\r\n onClick={() => onResponse('Yes', { volumeMultiplier: 1.0 })}\r\n className=\"px-4 py-3 bg-[#4399D1] hover:bg-[#2B7AB8] text-white rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Yes\r\n </button>\r\n <button\r\n onClick={() => onResponse('Volume is higher', { volumeMultiplier: 1.1 })}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Volume is higher\r\n </button>\r\n <button\r\n onClick={() => onResponse('Volume is lower', { volumeMultiplier: 0.9 })}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Volume is lower\r\n </button>\r\n </div>\r\n </motion.div>\r\n );\r\n }\r\n\r\n return (\r\n <motion.div initial={{ opacity: 0, y: 10 }} animate={{ opacity: 1, y: 0 }} className=\"space-y-3\">\r\n <div className=\"grid grid-cols-1 gap-2\">\r\n <button\r\n onClick={() => onResponse('Under $100M', { volume: 75000000 })}\r\n className=\"px-4 py-3 bg-[#4399D1] hover:bg-[#2B7AB8] text-white rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Under $100M\r\n </button>\r\n <button\r\n onClick={() => onResponse('$100M – $250M', { volume: 175000000 })}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n $100M – $250M\r\n </button>\r\n <button\r\n onClick={() => onResponse('$250M – $500M', { volume: 375000000 })}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n $250M – $500M\r\n </button>\r\n <button\r\n onClick={() => onResponse('$500M+', { volume: 650000000 })}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n $500M+\r\n </button>\r\n </div>\r\n </motion.div>\r\n );\r\n }\r\n\r\n if (step === 'economics') {\r\n return (\r\n <motion.div initial={{ opacity: 0, y: 10 }} animate={{ opacity: 1, y: 0 }} className=\"space-y-3\">\r\n <div className=\"grid grid-cols-1 gap-2\">\r\n <button\r\n onClick={() => onResponse('Sounds right', { margin: 3.0, grossProfit: 1.5, opEx: 0.75 })}\r\n className=\"px-4 py-3 bg-[#4399D1] hover:bg-[#2B7AB8] text-white rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Sounds right\r\n </button>\r\n <button\r\n onClick={() =>\r\n onResponse('Margin is higher', {\r\n margin: 3.5,\r\n grossProfit: 1.75,\r\n opEx: 0.75,\r\n })\r\n }\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Margin is higher\r\n </button>\r\n <button\r\n onClick={() =>\r\n onResponse('Expenses are higher', {\r\n margin: 3.0,\r\n grossProfit: 1.5,\r\n opEx: 0.95,\r\n })\r\n }\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Expenses are higher\r\n </button>\r\n <button\r\n onClick={() =>\r\n onResponse('Let me adjust', {\r\n margin: 3.0,\r\n grossProfit: 1.5,\r\n opEx: 0.75,\r\n })\r\n }\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Let me adjust\r\n </button>\r\n </div>\r\n </motion.div>\r\n );\r\n }\r\n\r\n if (step === 'complete') {\r\n return (\r\n <motion.div initial={{ opacity: 0, y: 10 }} animate={{ opacity: 1, y: 0 }} className=\"space-y-3\">\r\n <div className=\"grid grid-cols-1 gap-2\">\r\n <button\r\n onClick={() => onResponse('Sanity-check with AFN')}\r\n className=\"px-4 py-3 bg-[#4399D1] hover:bg-[#2B7AB8] text-white rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Sanity-check with AFN\r\n </button>\r\n <button\r\n onClick={() => onResponse('Adjust assumptions')}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Adjust assumptions\r\n </button>\r\n <button\r\n onClick={() => onResponse('Schedule leadership call')}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Schedule leadership call\r\n </button>\r\n </div>\r\n </motion.div>\r\n );\r\n }\r\n }\r\n\r\n return null;\r\n}\r\n\r\n","import React, { useState } from 'react';\r\n\r\nconst ERROR_IMG_SRC =\r\n 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iODgiIGhlaWdodD0iODgiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBvcGFjaXR5PSIuMyIgZmlsbD0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIzLjciPjxyZWN0IHg9IjE2IiB5PSIxNiIgd2lkdGg9IjU2IiBoZWlnaHQ9IjU2IiByeD0iNiIvPjxwYXRoIGQ9Im0xNiA1OCAxNi0xOCAzMiAzMiIvPjxjaXJjbGUgY3g9IjUzIiBjeT0iMzUiIHI9IjciLz48L3N2Zz4KCg==';\r\n\r\nexport function ImageWithFallback(props: React.ImgHTMLAttributes<HTMLImageElement>) {\r\n const [didError, setDidError] = useState(false);\r\n\r\n const handleError = () => {\r\n setDidError(true);\r\n };\r\n\r\n const { src, alt, style, className, ...rest } = props;\r\n\r\n return didError ? (\r\n <div\r\n className={`inline-block bg-gray-100 text-center align-middle ${className ?? ''}`}\r\n style={style}\r\n >\r\n <div className=\"flex items-center justify-center w-full h-full\">\r\n <img src={ERROR_IMG_SRC} alt=\"Error loading image\" {...rest} data-original-url={src} />\r\n </div>\r\n </div>\r\n ) : (\r\n <img src={src} alt={alt} className={className} style={style} {...rest} onError={handleError} />\r\n );\r\n}\r\n\r\n"],"mappings":"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","names":["import_react","import_lucide_react","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_jsx_runtime"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/lib/BradyChatContext.tsx","../src/lib/EnhancedBradyChat.tsx","../src/lib/api/afnBradyApi.ts","../src/lib/api/bradyHealth.ts","../src/lib/InfoRequestForm.tsx","../src/lib/LeadershipCallForm.tsx","../src/lib/PersonalizedOverviewForm.tsx","../src/lib/QuickSuggestions.tsx","../src/lib/ModePromptTree.tsx","../src/lib/ImageWithFallback.tsx"],"sourcesContent":["export * from './lib/BradyChatContext';\r\nexport * from './lib/EnhancedBradyChat';\r\nexport * from './lib/api/afnBradyApi';\r\nexport * from './lib/api/bradyHealth';\r\n","'use client';\r\n\r\nimport React, { createContext, useContext, useState, ReactNode } from 'react';\r\n\r\nexport type ChatWorkflowType =\r\n | 'free'\r\n | 'info-request'\r\n | 'leadership-call'\r\n | 'personalized-overview-request'\r\n | 'earnings-mode'\r\n | 'profit-mode';\r\nexport type ModeType = 'none' | 'earnings' | 'profit';\r\nexport type ModeStep = 'initial' | 'volume' | 'comp' | 'economics' | 'calculator' | 'complete';\r\n\r\nexport interface ChatMessage {\r\n type: 'user' | 'brady' | 'form';\r\n text?: string;\r\n component?: ReactNode;\r\n}\r\n\r\ninterface ModeData {\r\n volume?: number;\r\n comp?: number;\r\n margin?: number;\r\n grossProfit?: number;\r\n opEx?: number;\r\n volumeMultiplier?: number;\r\n}\r\n\r\ninterface BradyChatContextType {\r\n workflowType: ChatWorkflowType;\r\n messages: ChatMessage[];\r\n startWorkflow: (workflow: ChatWorkflowType) => void;\r\n addMessage: (message: ChatMessage) => void;\r\n setWorkflow: (workflow: ChatWorkflowType) => void;\r\n resetChat: () => void;\r\n // Mode system\r\n activeMode: ModeType;\r\n modeStep: ModeStep;\r\n modeData: ModeData;\r\n activateMode: (mode: ModeType) => void;\r\n setModeStep: (step: ModeStep) => void;\r\n updateModeData: (data: Partial<ModeData>) => void;\r\n resetMode: () => void;\r\n // Calculator control\r\n calculatorOpen: boolean;\r\n setCalculatorOpen: (open: boolean) => void;\r\n isHidden: boolean;\r\n setIsHidden: React.Dispatch<React.SetStateAction<boolean>>;\r\n // Modal-aware Brady AI\r\n hideBradyForModal: () => void;\r\n restoreBradyAfterModal: () => void;\r\n}\r\n\r\nconst BradyChatContext = createContext<BradyChatContextType | undefined>(undefined);\r\n\r\nconst initialMessages: ChatMessage[] = [\r\n {\r\n type: 'user',\r\n text: \"introduce\",\r\n },\r\n];\r\n\r\nexport function BradyChatProvider({ children }: { children: ReactNode }) {\r\n const [workflowType, setWorkflowType] = useState<ChatWorkflowType>('free');\r\n const [messages, setMessages] = useState<ChatMessage[]>(initialMessages);\r\n // Mode system state\r\n const [activeMode, setActiveMode] = useState<ModeType>('none');\r\n const [modeStep, setModeStep] = useState<ModeStep>('initial');\r\n const [modeData, setModeData] = useState<ModeData>({});\r\n const [calculatorOpen, setCalculatorOpen] = useState(false);\r\n // Global hide/show state for Brady chat (default hidden)\r\n const [isHidden, setIsHidden] = useState(true);\r\n // Track previous visibility for modal\r\n const [wasBradyVisibleBeforeModal, setWasBradyVisibleBeforeModal] = useState(false);\r\n\r\n // Modal-aware hide/show\r\n const hideBradyForModal = () => {\r\n setWasBradyVisibleBeforeModal(!isHidden);\r\n setIsHidden(true);\r\n };\r\n const restoreBradyAfterModal = () => {\r\n if (wasBradyVisibleBeforeModal) setIsHidden(false);\r\n };\r\n\r\n const startWorkflow = (workflow: ChatWorkflowType) => {\r\n setWorkflowType(workflow);\r\n\r\n // Set appropriate initial message based on workflow\r\n if (workflow === 'info-request') {\r\n setMessages([\r\n {\r\n type: 'brady',\r\n text: \"Happy to send you a personalized overview.\\n\\nIf you share your contact details below, we'll email you more information about AFN and how it could fit your goals.\",\r\n },\r\n ]);\r\n } else if (workflow === 'leadership-call') {\r\n setMessages([\r\n {\r\n type: 'brady',\r\n text: \"Happy to connect you with AFN leadership.\\n\\nShare your details below and we'll have someone reach out shortly.\\nIf you'd like, you can also suggest a good time to talk.\",\r\n },\r\n ]);\r\n } else if (workflow === 'personalized-overview-request') {\r\n setMessages([\r\n {\r\n type: 'brady',\r\n text: \"I'll help you get a personalized dashboard and earnings calculator.\\n\\nShare your details below and we'll create a custom overview showing exactly what your business could look like at AFN.\",\r\n },\r\n ]);\r\n } else {\r\n setMessages(initialMessages);\r\n }\r\n };\r\n\r\n const addMessage = (message: ChatMessage) => {\r\n setMessages((prev) => [...prev, message]);\r\n };\r\n\r\n const setWorkflow = (workflow: ChatWorkflowType) => {\r\n setWorkflowType(workflow);\r\n };\r\n\r\n const resetChat = () => {\r\n setWorkflowType('free');\r\n setMessages(initialMessages);\r\n resetMode();\r\n };\r\n\r\n // Mode system functions\r\n const activateMode = (mode: ModeType) => {\r\n setActiveMode(mode);\r\n setModeStep('initial');\r\n setModeData({});\r\n\r\n // Set initial mode message\r\n if (mode === 'earnings') {\r\n setMessages([\r\n {\r\n type: 'brady',\r\n text: \"Earnings Mode is on.\\n\\nI'll focus on how volume, efficiency, and time savings can impact your income.\",\r\n },\r\n ]);\r\n setModeStep('volume');\r\n } else if (mode === 'profit') {\r\n setMessages([\r\n {\r\n type: 'brady',\r\n text: 'Profit Mode is on.\\n\\nI\\'ll focus on branch economics—volume, margin, expenses, and profitability.',\r\n },\r\n ]);\r\n setModeStep('volume');\r\n }\r\n };\r\n\r\n const updateModeData = (data: Partial<ModeData>) => {\r\n setModeData((prev) => ({ ...prev, ...data }));\r\n };\r\n\r\n const resetMode = () => {\r\n setActiveMode('none');\r\n setModeStep('initial');\r\n setModeData({});\r\n setCalculatorOpen(false);\r\n };\r\n\r\n return (\r\n <BradyChatContext.Provider\r\n value={{\r\n workflowType,\r\n messages,\r\n startWorkflow,\r\n addMessage,\r\n setWorkflow,\r\n resetChat,\r\n activeMode,\r\n modeStep,\r\n modeData,\r\n activateMode,\r\n setModeStep,\r\n updateModeData,\r\n resetMode,\r\n calculatorOpen,\r\n setCalculatorOpen,\r\n isHidden,\r\n setIsHidden,\r\n hideBradyForModal,\r\n restoreBradyAfterModal,\r\n }}\r\n >\r\n {children}\r\n </BradyChatContext.Provider>\r\n );\r\n}\r\n\r\nexport function useBradyChat() {\r\n const context = useContext(BradyChatContext);\r\n if (context === undefined) {\r\n throw new Error('useBradyChat must be used within a BradyChatProvider');\r\n }\r\n return context;\r\n}\r\n\r\n","'use client';\r\n\r\nimport { useState, useRef, useEffect } from 'react';\r\nimport { motion, AnimatePresence } from 'motion/react';\r\nimport { Send, Mic } from 'lucide-react';\r\n\r\nimport { checkBradyHealth } from './api/bradyHealth';\r\nimport { sendBradyPrompt } from './api/afnBradyApi';\r\nimport { useBradyChat } from './BradyChatContext';\r\nimport { InfoRequestForm } from './InfoRequestForm';\r\nimport { LeadershipCallForm } from './LeadershipCallForm';\r\nimport { PersonalizedOverviewForm } from './PersonalizedOverviewForm';\r\nimport { QuickSuggestions } from './QuickSuggestions';\r\nimport { ModePromptTree } from './ModePromptTree';\r\nimport { ImageWithFallback } from './ImageWithFallback';\r\n\r\ntype ModeVariant = 'loan-officer' | 'branch-manager';\r\n\r\nexport interface EnhancedBradyChatProps {\r\n /**\r\n * Controls whether the mode toggle uses Earnings (LO) or Profit (branch manager) language.\r\n * Defaults to 'loan-officer'.\r\n */\r\n modeVariant?: ModeVariant;\r\n /**\r\n * Avatar image URL for Brady.\r\n * Typically you pass something like `/bradyIcon.png` from your app's public assets.\r\n */\r\n avatarSrc: string;\r\n}\r\n\r\nexport function EnhancedBradyChat({ modeVariant = 'loan-officer', avatarSrc }: EnhancedBradyChatProps) {\r\n const [bradyHealthy, setBradyHealthy] = useState(true);\r\n const {\r\n workflowType,\r\n messages,\r\n addMessage,\r\n resetChat,\r\n setWorkflow,\r\n activeMode,\r\n modeStep,\r\n modeData,\r\n setModeStep,\r\n updateModeData,\r\n setCalculatorOpen,\r\n activateMode,\r\n resetMode,\r\n isHidden,\r\n setIsHidden,\r\n } = useBradyChat();\r\n const [inputValue, setInputValue] = useState('');\r\n const [showForm, setShowForm] = useState(false);\r\n const [inputDisabled, setInputDisabled] = useState(false);\r\n const [showModePrompts, setShowModePrompts] = useState(false);\r\n const messagesEndRef = useRef<HTMLDivElement>(null);\r\n const [suggestionLinks, setSuggestionLinks] = useState<{ text: string; prompt: string }[] | null>(null);\r\n\r\n const isBranchManager = modeVariant === 'branch-manager';\r\n const pageMode = isBranchManager ? 'profit' : 'earnings';\r\n const isModeActive = activeMode === pageMode;\r\n const hasPersonalizedData = false;\r\n\r\n const handleFocusToggle = () => {\r\n if (isModeActive) {\r\n resetMode();\r\n } else {\r\n activateMode(pageMode);\r\n setTimeout(() => {\r\n addMessage({\r\n type: 'brady',\r\n text: `${\r\n isBranchManager ? 'Profit' : 'Earnings'\r\n } Mode is on.\\n\\nI'll focus on ways to increase ${\r\n isBranchManager ? 'profit' : 'income'\r\n } using ${\r\n isBranchManager\r\n ? 'branch economics, recruiting leverage, and operational efficiency'\r\n : 'volume, efficiency, and time savings'\r\n }.`,\r\n });\r\n }, 300);\r\n }\r\n };\r\n\r\n useEffect(() => {\r\n let mounted = true;\r\n const checkHealth = async () => {\r\n const healthy = await checkBradyHealth();\r\n if (mounted) setBradyHealthy(healthy);\r\n };\r\n checkHealth();\r\n const interval = setInterval(checkHealth, 60000);\r\n return () => {\r\n mounted = false;\r\n clearInterval(interval);\r\n };\r\n }, []);\r\n\r\n useEffect(() => {\r\n if (\r\n workflowType === 'info-request' ||\r\n workflowType === 'leadership-call' ||\r\n workflowType === 'personalized-overview-request'\r\n ) {\r\n setShowForm(true);\r\n setInputDisabled(true);\r\n setShowModePrompts(false);\r\n } else {\r\n setShowForm(false);\r\n setInputDisabled(false);\r\n }\r\n }, [workflowType]);\r\n\r\n useEffect(() => {\r\n if (activeMode !== 'none' && modeStep === 'volume') {\r\n setShowModePrompts(true);\r\n\r\n if (activeMode === 'earnings') {\r\n if (hasPersonalizedData) {\r\n setTimeout(() => {\r\n addMessage({\r\n type: 'brady',\r\n text: 'I have an estimate of your recent production.\\nDoes this feel close?',\r\n });\r\n }, 500);\r\n } else {\r\n setTimeout(() => {\r\n addMessage({\r\n type: 'brady',\r\n text: 'To keep this realistic, about how much volume do you fund in an average month?',\r\n });\r\n }, 500);\r\n }\r\n } else if (activeMode === 'profit') {\r\n if (hasPersonalizedData) {\r\n setTimeout(() => {\r\n addMessage({\r\n type: 'brady',\r\n text: 'I have a baseline view of your branch.\\nDoes this feel directionally right?',\r\n });\r\n }, 500);\r\n } else {\r\n setTimeout(() => {\r\n addMessage({\r\n type: 'brady',\r\n text: 'To start, about how much volume does your branch fund annually?',\r\n });\r\n }, 500);\r\n }\r\n }\r\n }\r\n }, [activeMode, modeStep, addMessage]);\r\n\r\n useEffect(() => {\r\n scrollToBottom();\r\n }, [messages, showForm, showModePrompts]);\r\n\r\n const scrollToBottom = () => {\r\n messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });\r\n };\r\n\r\n const handleModeResponse = (response: string, data?: any) => {\r\n addMessage({ type: 'user', text: response });\r\n setShowModePrompts(false);\r\n\r\n if (data) {\r\n updateModeData(data);\r\n }\r\n\r\n if (activeMode === 'earnings') {\r\n if (modeStep === 'volume') {\r\n setTimeout(() => {\r\n addMessage({\r\n type: 'brady',\r\n text: 'And roughly how do you get paid today?',\r\n });\r\n setModeStep('comp');\r\n setShowModePrompts(true);\r\n }, 800);\r\n } else if (modeStep === 'comp') {\r\n setTimeout(() => {\r\n addMessage({\r\n type: 'brady',\r\n text: \"Got it. I'll pull this together so you can see it clearly.\",\r\n });\r\n setModeStep('calculator');\r\n setTimeout(() => {\r\n setCalculatorOpen(true);\r\n setModeStep('complete');\r\n setTimeout(() => {\r\n addMessage({\r\n type: 'brady',\r\n text: 'Want to sanity-check these assumptions together?',\r\n });\r\n setShowModePrompts(true);\r\n }, 1000);\r\n }, 800);\r\n }, 800);\r\n } else if (modeStep === 'complete') {\r\n if (response.includes('Talk through')) {\r\n setShowModePrompts(false);\r\n setTimeout(() => {\r\n startWorkflow('leadership-call');\r\n }, 500);\r\n } else if (response.includes('Adjust')) {\r\n setShowModePrompts(false);\r\n setTimeout(() => {\r\n setCalculatorOpen(true);\r\n }, 500);\r\n } else {\r\n setShowModePrompts(false);\r\n setTimeout(() => {\r\n addMessage({\r\n type: 'brady',\r\n text: \"I'm here whenever you need me. What else would you like to explore?\",\r\n });\r\n }, 800);\r\n }\r\n }\r\n } else if (activeMode === 'profit') {\r\n if (modeStep === 'volume') {\r\n setTimeout(() => {\r\n addMessage({\r\n type: 'brady',\r\n text:\r\n \"For modeling, I'll assume:\\n• ~300 bps branch margin\\n• ~150 bps gross profit\\n\" +\r\n '• ~75 bps operating expenses\\n\\nWe can adjust all of this.',\r\n });\r\n setModeStep('economics');\r\n setShowModePrompts(true);\r\n }, 800);\r\n } else if (modeStep === 'economics') {\r\n setTimeout(() => {\r\n addMessage({\r\n type: 'brady',\r\n text: \"Here's a clean P&L view based on what we discussed.\",\r\n });\r\n setModeStep('calculator');\r\n setTimeout(() => {\r\n setCalculatorOpen(true);\r\n setModeStep('complete');\r\n setTimeout(() => {\r\n addMessage({\r\n type: 'brady',\r\n text: \"Want help building a realistic pro forma based on AFN's structure?\",\r\n });\r\n setShowModePrompts(true);\r\n }, 1000);\r\n }, 800);\r\n }, 800);\r\n } else if (modeStep === 'complete') {\r\n if (response.includes('Sanity-check') || response.includes('leadership')) {\r\n setShowModePrompts(false);\r\n setTimeout(() => {\r\n startWorkflow('leadership-call');\r\n }, 500);\r\n } else if (response.includes('Adjust')) {\r\n setShowModePrompts(false);\r\n setTimeout(() => {\r\n setCalculatorOpen(true);\r\n }, 500);\r\n }\r\n }\r\n }\r\n };\r\n\r\n const handleSend = async () => {\r\n if (inputValue.trim() && !inputDisabled) {\r\n const userText = inputValue;\r\n addMessage({ type: 'user', text: userText });\r\n setInputValue('');\r\n \r\n try {\r\n const apiResponse = await sendBradyPrompt([{ role: 'user', content: userText }]);\r\n let mappedType: 'user' | 'brady' | 'form' = 'brady';\r\n if (apiResponse.role === 'user') mappedType = 'user';\r\n addMessage({ type: mappedType, text: apiResponse.content });\r\n } catch {\r\n addMessage({ type: 'brady', text: 'Sorry, Brady AI is currently unavailable.' });\r\n }\r\n }\r\n };\r\n\r\n const handleQuickSuggestion = async (text: string) => {\r\n addMessage({ type: 'user', text });\r\n try {\r\n const apiResponse = await sendBradyPrompt([{ role: 'user', content: text }]);\r\n\r\n if (Array.isArray(apiResponse.suggestionLink)) {\r\n setSuggestionLinks(apiResponse.suggestionLink);\r\n }\r\n\r\n let mappedType: 'user' | 'brady' | 'form' = 'brady';\r\n if (apiResponse.role === 'user') mappedType = 'user';\r\n addMessage({ type: mappedType, text: apiResponse.content });\r\n } catch {\r\n addMessage({ type: 'brady', text: 'Sorry, Brady AI is currently unavailable.' });\r\n }\r\n };\r\n\r\n const handleInfoFormSubmit = (data: any) => {\r\n addMessage({\r\n type: 'brady',\r\n text:\r\n \"Got it — thanks.\\n\\nWe'll email you a personalized overview shortly.\\nIf you have questions in the meantime, I'm here to help.\",\r\n });\r\n setShowForm(false);\r\n setInputDisabled(false);\r\n setWorkflow('free');\r\n };\r\n\r\n const handleLeadershipFormSubmit = (data: any) => {\r\n addMessage({\r\n type: 'brady',\r\n text:\r\n \"Thanks — you're all set.\\n\\nSomeone from AFN leadership will reach out shortly to connect.\\nIn the meantime, feel free to ask me anything.\",\r\n });\r\n setShowForm(false);\r\n setInputDisabled(false);\r\n setWorkflow('free');\r\n };\r\n\r\n const handlePersonalizedOverviewFormSubmit = (data: any) => {\r\n addMessage({\r\n type: 'brady',\r\n text:\r\n \"Perfect — thanks!\\n\\nWe'll create a personalized dashboard and earnings calculator based on your information and send it to you shortly.\\n\\nYou'll be able to see exactly what your business could look like at AFN with specific projections tailored to your situation.\",\r\n });\r\n setShowForm(false);\r\n setInputDisabled(false);\r\n setWorkflow('free');\r\n };\r\n\r\n const handleFormCancel = () => {\r\n setShowForm(false);\r\n setInputDisabled(false);\r\n resetChat();\r\n };\r\n\r\n const buildSuggestions = () => {\r\n if (suggestionLinks && suggestionLinks.length > 0) {\r\n return suggestionLinks.map((s) => ({\r\n text: s.text,\r\n action: () => handleQuickSuggestion(s.prompt),\r\n }));\r\n }\r\n return [];\r\n };\r\n\r\n const initialSuggestions = buildSuggestions();\r\n const postSubmitSuggestions = buildSuggestions();\r\n\r\n const showPostSubmitSuggestions = messages.length > 2 && !showForm && workflowType === 'free' && activeMode === 'none';\r\n\r\n const startWorkflow = (workflow: any) => {\r\n setWorkflow(workflow);\r\n if (workflow === 'info-request') {\r\n setShowForm(true);\r\n setInputDisabled(true);\r\n } else if (workflow === 'leadership-call') {\r\n setShowForm(true);\r\n setInputDisabled(true);\r\n }\r\n };\r\n\r\n const modeBadge =\r\n activeMode !== 'none' ? (\r\n <div\r\n className={`px-3 py-1 rounded-full text-xs font-medium ${\r\n activeMode === 'earnings'\r\n ? 'bg-[#8B5CF6]/20 text-[#8B5CF6] border border-[#8B5CF6]/30'\r\n : 'bg-[#4399D1]/20 text-[#4399D1] border border-[#4399D1]/30'\r\n }`}\r\n >\r\n {activeMode === 'earnings' ? 'Earnings Mode' : 'Profit Mode'}\r\n </div>\r\n ) : null;\r\n\r\n if (isHidden) return null;\r\n \r\n\r\n return (\r\n <div className=\"fixed top-0 right-0 w-full md:w-[360px] h-screen flex flex-col bg-gradient-to-br dark:from-zinc-900 dark:to-zinc-800 from-white to-zinc-50 border-l md:border-l dark:border-zinc-700 border-zinc-300 shadow-2xl z-[100] overflow-hidden transition-all duration-300\">\r\n <div className=\"flex items-center justify-between px-4 py-3 border-b dark:border-zinc-800 border-zinc-200 dark:bg-zinc-950/80 bg-white/95 backdrop-blur-lg\">\r\n <div className=\"flex items-center gap-3\">\r\n <div className=\"relative\">\r\n <span className=\"relative w-10 h-10 block group\">\r\n <span\r\n className={`absolute inset-0 rounded-full transition-colors duration-300 ${\r\n bradyHealthy ? 'dark:bg-zinc-700/40 bg-transparent' : 'bg-red-600/80 dark:bg-red-700/80'\r\n }`}\r\n ></span>\r\n <ImageWithFallback\r\n src={avatarSrc}\r\n alt=\"Brady AI\"\r\n className=\"w-10 h-10 relative z-10\"\r\n onClick={() => setIsHidden(true)}\r\n />\r\n </span>\r\n </div>\r\n <div className=\"dark:text-white text-zinc-900\">Brady AI</div>\r\n </div>\r\n\r\n <div className=\"relative inline-flex items-center h-[34px] w-[150px] dark:bg-zinc-800/50 bg-zinc-200 rounded-full p-1\">\r\n <button\r\n onClick={() => isModeActive && resetMode()}\r\n className={`relative z-10 flex-1 h-full rounded-full text-[11px] tracking-wide uppercase font-medium transition-all duration-300 flex items-center justify-center ${\r\n !isModeActive\r\n ? 'text-white'\r\n : 'dark:text-zinc-500 text-zinc-600 hover:dark:bg-zinc-700/50 hover:bg-zinc-300/50'\r\n }`}\r\n >\r\n NORMAL\r\n </button>\r\n\r\n <div className=\"relative flex-1\">\r\n {!isModeActive && (\r\n <div\r\n className=\"absolute inset-0 rounded-full animate-pulse\"\r\n style={{\r\n boxShadow: isBranchManager\r\n ? '0 0 16px rgba(67, 153, 209, 0.6), inset 0 0 10px rgba(67, 153, 209, 0.3)'\r\n : '0 0 16px rgba(139, 92, 246, 0.6), inset 0 0 10px rgba(139, 92, 246, 0.3)',\r\n animation: 'pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite',\r\n }}\r\n />\r\n )}\r\n <button\r\n onClick={() => !isModeActive && handleFocusToggle()}\r\n className={`relative z-10 w-full h-full rounded-full text-[11px] tracking-wide uppercase font-medium transition-all duration-300 flex items-center justify-center ${\r\n isModeActive\r\n ? 'text-white'\r\n : 'dark:text-zinc-500 text-zinc-600 hover:dark:bg-zinc-700/50 hover:bg-zinc-300/50'\r\n }`}\r\n >\r\n {isBranchManager ? 'PROFIT' : 'EARNINGS'}\r\n </button>\r\n </div>\r\n\r\n <div\r\n className={`absolute top-1 bottom-1 rounded-full transition-all duration-300 ${\r\n isModeActive ? 'left-[50%] right-1' : 'left-1 right-[50%]'\r\n }`}\r\n style={\r\n isModeActive\r\n ? {\r\n background: isBranchManager\r\n ? 'linear-gradient(135deg, #4399D1 0%, #3b82d9 100%)'\r\n : 'linear-gradient(135deg, #8B5CF6 0%, #7C3AED 100%)',\r\n boxShadow: isBranchManager\r\n ? '0 0 16px rgba(67, 153, 209, 0.15)'\r\n : '0 0 16px rgba(139, 92, 246, 0.15)',\r\n }\r\n : {\r\n background: 'var(--tw-gradient-stops)',\r\n backgroundImage: 'linear-gradient(135deg, rgb(82, 82, 91) 0%, rgb(63, 63, 70) 100%)',\r\n }\r\n }\r\n />\r\n </div>\r\n </div>\r\n\r\n {modeBadge && (\r\n <div className=\"px-4 py-2 border-b dark:border-zinc-800 border-zinc-200\">\r\n {modeBadge}\r\n </div>\r\n )}\r\n\r\n {!bradyHealthy && (\r\n\r\n <div className=\"fixed top-0 right-0 w-full md:w-[360px] h-screen flex flex-col bg-gradient-to-br dark:from-zinc-900 dark:to-zinc-800 from-white to-zinc-50 border-l md:border-l dark:border-zinc-700 border-zinc-300 shadow-2xl z-[100] overflow-hidden transition-all duration-300 items-center justify-center\">\r\n <div className=\"text-center text-zinc-500 dark:text-zinc-400 text-lg font-medium\">\r\n Sorry, Brady AI is currently unavailable.\r\n </div>\r\n </div>\r\n )}\r\n <div className=\"flex-1 overflow-y-auto p-4 space-y-4\">\r\n <AnimatePresence>\r\n {messages.map((msg, idx) => (\r\n <motion.div\r\n key={idx}\r\n initial={{ opacity: 0, y: 10 }}\r\n animate={{ opacity: 1, y: 0 }}\r\n className={`flex ${msg.type === 'user' ? 'justify-end' : 'justify-start'}`}\r\n >\r\n <div\r\n className={`px-4 py-3 rounded-2xl whitespace-pre-line ${\r\n msg.type === 'user'\r\n ? 'bg-[#8B5CF6] text-white rounded-br-sm'\r\n : 'dark:bg-zinc-800 bg-zinc-100 dark:text-zinc-100 text-zinc-900 rounded-bl-sm'\r\n }`}\r\n >\r\n {msg.text === 'introduce' ? '' : msg.text}\r\n </div>\r\n </motion.div>\r\n ))}\r\n </AnimatePresence>\r\n\r\n {showForm && workflowType === 'info-request' && (\r\n <InfoRequestForm onSubmit={handleInfoFormSubmit} onCancel={handleFormCancel} />\r\n )}\r\n\r\n {showForm && workflowType === 'leadership-call' && (\r\n <LeadershipCallForm onSubmit={handleLeadershipFormSubmit} onCancel={handleFormCancel} />\r\n )}\r\n\r\n {showForm && workflowType === 'personalized-overview-request' && (\r\n <PersonalizedOverviewForm\r\n onSubmit={handlePersonalizedOverviewFormSubmit}\r\n onCancel={handleFormCancel}\r\n />\r\n )}\r\n\r\n {showModePrompts && activeMode !== 'none' && (\r\n <ModePromptTree\r\n mode={activeMode as 'earnings' | 'profit'}\r\n step={modeStep}\r\n hasPersonalizedData={hasPersonalizedData}\r\n onResponse={handleModeResponse}\r\n />\r\n )}\r\n\r\n {!showForm &&\r\n !showModePrompts &&\r\n messages.length === 1 &&\r\n workflowType === 'free' &&\r\n activeMode === 'none' && <QuickSuggestions suggestions={initialSuggestions} />}\r\n\r\n {showPostSubmitSuggestions && !showModePrompts && (\r\n <QuickSuggestions suggestions={postSubmitSuggestions} />\r\n )}\r\n\r\n <div ref={messagesEndRef} />\r\n </div>\r\n\r\n <div className=\"p-4 border-t dark:border-zinc-800 border-zinc-200 dark:bg-zinc-900 bg-zinc-50\">\r\n <div\r\n className={`flex items-center gap-2 dark:bg-zinc-800 bg-white rounded-full px-4 py-3 border dark:border-zinc-700 border-zinc-300 focus-within:border-[#8B5CF6] transition-colors ${\r\n inputDisabled || showModePrompts ? 'opacity-50 cursor-not-allowed' : ''\r\n }`}\r\n >\r\n <input\r\n type=\"text\"\r\n value={inputValue}\r\n onChange={(e) => setInputValue(e.target.value)}\r\n onKeyPress={(e) => e.key === 'Enter' && handleSend()}\r\n placeholder={\r\n inputDisabled || showModePrompts ? 'Use buttons above...' : 'Ask me anything...'\r\n }\r\n disabled={inputDisabled || showModePrompts}\r\n className=\"flex-1 bg-transparent dark:text-white text-zinc-900 dark:placeholder-zinc-500 placeholder-zinc-400 outline-none text-sm disabled:cursor-not-allowed\"\r\n />\r\n <button\r\n className=\"dark:text-zinc-400 text-zinc-500 dark:hover:text-white hover:text-zinc-900 transition-colors disabled:opacity-50\"\r\n disabled={inputDisabled || showModePrompts}\r\n >\r\n <Mic className=\"w-5 h-5\" />\r\n </button>\r\n <button\r\n onClick={handleSend}\r\n disabled={inputDisabled || showModePrompts}\r\n className=\"bg-[#8B5CF6] hover:bg-[#7C3AED] text-white rounded-full p-2 transition-colors disabled:opacity-50 disabled:cursor-not-allowed\"\r\n >\r\n <Send className=\"w-4 h-4\" />\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\n","// afnBradyApi.ts (library version)\r\n// Utility for integrating with AFN Brady Jr API\r\n\r\n// Use environment variable for API key\r\n// Supports both server (BRADY_API_KEY, BRADY_API_URL) and browser (NEXT_PUBLIC_BRADY_API_KEY, NEXT_PUBLIC_BRADY_API_URL)\r\n// Consumers: Set NEXT_PUBLIC_BRADY_API_KEY and NEXT_PUBLIC_BRADY_API_URL in your app's .env.local for browser use\r\nexport const DEFAULT_BRADY_API_KEY =\r\n typeof process !== 'undefined' && process.env && (\r\n process.env.BRADY_API_KEY || process.env.NEXT_PUBLIC_BRADY_API_KEY\r\n )\r\n ? process.env.BRADY_API_KEY || process.env.NEXT_PUBLIC_BRADY_API_KEY\r\n : 'za2345DDDzXycXKHJvVj80TIsPgooB7iNbwcS9KLzoeaOljlXmJQQJ99BJAC4f1cMXJ3w3AAABACOGQzXz';\r\n\r\nexport const API_URL =\r\n typeof process !== 'undefined' && process.env && (\r\n process.env.BRADY_API_URL || process.env.NEXT_PUBLIC_BRADY_API_URL\r\n )\r\n ? process.env.BRADY_API_URL || process.env.NEXT_PUBLIC_BRADY_API_URL\r\n : 'https://afn-bradyjr-api-dev.azurewebsites.net/';\r\n\r\nexport interface BradyMessage {\r\n role: 'user' | 'assistant' | 'system';\r\n content: string;\r\n}\r\n\r\nexport interface BradyChatRequest {\r\n messages: BradyMessage[];\r\n}\r\n\r\nexport interface BradyChatResponse {\r\n role: string;\r\n type: string;\r\n content: string;\r\n suggestionLink?: { text: string; prompt: string }[];\r\n}\r\n\r\nexport async function sendBradyPrompt(\r\n messages: BradyMessage[],\r\n apiKey: string = DEFAULT_BRADY_API_KEY\r\n): Promise<BradyChatResponse> {\r\n\r\n console.log('[DEFAULT_BRADY_API_KEY]', DEFAULT_BRADY_API_KEY);\r\n console.log('[API_URL]', API_URL);\r\n\r\n const res = await fetch(`${API_URL}/api/chat/prompt`, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'X-API-KEY': apiKey\r\n },\r\n body: JSON.stringify({ messages })\r\n });\r\n if (!res.ok) throw new Error('Brady API error: ' + res.status);\r\n const data = await res.json();\r\n if (process.env.NODE_ENV === 'development') {\r\n // eslint-disable-next-line no-console\r\n console.log('[Brady API Response]', data);\r\n }\r\n return data;\r\n}\r\n\r\n","// bradyHealth.ts (library version)\r\n// Utility to check health of Brady AI API\r\n\r\nimport { API_URL } from './afnBradyApi';\r\n\r\nexport async function checkBradyHealth(): Promise<boolean> {\r\n try {\r\n const res = await fetch(`${API_URL}/api/Health`);\r\n if (!res.ok) return false;\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\n","'use client';\r\n\r\nimport React, { useState } from 'react';\r\nimport { motion } from 'motion/react';\r\n\r\ninterface InfoRequestFormProps {\r\n onSubmit: (data: { firstName: string; lastName: string; email: string; phone?: string }) => void;\r\n onCancel: () => void;\r\n}\r\n\r\nexport function InfoRequestForm({ onSubmit, onCancel }: InfoRequestFormProps) {\r\n const [formData, setFormData] = useState({\r\n firstName: '',\r\n lastName: '',\r\n email: '',\r\n phone: '',\r\n });\r\n const [errors, setErrors] = useState<Record<string, string>>({});\r\n\r\n const handleSubmit = (e: React.FormEvent) => {\r\n e.preventDefault();\r\n const newErrors: Record<string, string> = {};\r\n\r\n if (!formData.firstName.trim()) {\r\n newErrors.firstName = 'First name is required';\r\n }\r\n if (!formData.lastName.trim()) {\r\n newErrors.lastName = 'Last name is required';\r\n }\r\n if (!formData.email.trim()) {\r\n newErrors.email = 'Email is required';\r\n } else if (!/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(formData.email)) {\r\n newErrors.email = 'Please enter a valid email address';\r\n }\r\n\r\n if (Object.keys(newErrors).length > 0) {\r\n setErrors(newErrors);\r\n return;\r\n }\r\n\r\n onSubmit(formData);\r\n };\r\n\r\n return (\r\n <motion.div\r\n initial={{ opacity: 0, y: 10 }}\r\n animate={{ opacity: 1, y: 0 }}\r\n className=\"bg-gradient-to-br from-white to-zinc-50 dark:from-zinc-800 dark:to-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-2xl p-6 max-h-[360px]\"\r\n >\r\n <h3 className=\"text-lg text-zinc-900 dark:text-white mb-4\">Send Me More Information</h3>\r\n\r\n <form onSubmit={handleSubmit} className=\"space-y-3\">\r\n <div>\r\n <input\r\n type=\"text\"\r\n placeholder=\"First Name\"\r\n value={formData.firstName}\r\n onChange={(e) => setFormData({ ...formData, firstName: e.target.value })}\r\n className=\"w-full px-4 py-2.5 bg-white dark:bg-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-lg text-zinc-900 dark:text-white placeholder-zinc-500 focus:border-[#8B5CF6] focus:outline-none transition-colors\"\r\n />\r\n {errors.firstName && <p className=\"text-red-500 text-xs mt-1\">{errors.firstName}</p>}\r\n </div>\r\n\r\n <div>\r\n <input\r\n type=\"text\"\r\n placeholder=\"Last Name\"\r\n value={formData.lastName}\r\n onChange={(e) => setFormData({ ...formData, lastName: e.target.value })}\r\n className=\"w-full px-4 py-2.5 bg-white dark:bg-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-lg text-zinc-900 dark:text-white placeholder-zinc-500 focus:border-[#8B5CF6] focus:outline-none transition-colors\"\r\n />\r\n {errors.lastName && <p className=\"text-red-500 text-xs mt-1\">{errors.lastName}</p>}\r\n </div>\r\n\r\n <div>\r\n <input\r\n type=\"email\"\r\n placeholder=\"Email Address\"\r\n value={formData.email}\r\n onChange={(e) => setFormData({ ...formData, email: e.target.value })}\r\n className=\"w-full px-4 py-2.5 bg-white dark:bg-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-lg text-zinc-900 dark:text-white placeholder-zinc-500 focus:border-[#8B5CF6] focus:outline-none transition-colors\"\r\n />\r\n {errors.email && <p className=\"text-red-500 text-xs mt-1\">{errors.email}</p>}\r\n </div>\r\n\r\n <div>\r\n <input\r\n type=\"tel\"\r\n placeholder=\"Phone (optional)\"\r\n value={formData.phone}\r\n onChange={(e) => setFormData({ ...formData, phone: e.target.value })}\r\n className=\"w-full px-4 py-2.5 bg-white dark:bg-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-lg text-zinc-900 dark:text-white placeholder-zinc-500 focus:border-[#8B5CF6] focus:outline-none transition-colors\"\r\n />\r\n </div>\r\n\r\n <div className=\"flex gap-2 pt-2\">\r\n <button\r\n type=\"submit\"\r\n className=\"flex-1 bg-[#8B5CF6] hover:bg-[#7C3AED] text-white py-2.5 rounded-lg transition-colors\"\r\n >\r\n Send Information\r\n </button>\r\n <button\r\n type=\"button\"\r\n onClick={onCancel}\r\n className=\"px-4 text-zinc-600 dark:text-zinc-400 hover:text-zinc-900 dark:hover:text-white transition-colors\"\r\n >\r\n Cancel\r\n </button>\r\n </div>\r\n </form>\r\n </motion.div>\r\n );\r\n}\r\n\r\n","'use client';\r\n\r\nimport React, { useState } from 'react';\r\nimport { motion } from 'motion/react';\r\nimport { Calendar, Clock } from 'lucide-react';\r\n\r\ninterface LeadershipCallFormProps {\r\n onSubmit: (data: {\r\n firstName: string;\r\n lastName: string;\r\n email: string;\r\n phone: string;\r\n preferredDate?: string;\r\n preferredTime?: string;\r\n }) => void;\r\n onCancel: () => void;\r\n}\r\n\r\nexport function LeadershipCallForm({ onSubmit, onCancel }: LeadershipCallFormProps) {\r\n const [formData, setFormData] = useState({\r\n firstName: '',\r\n lastName: '',\r\n email: '',\r\n phone: '',\r\n preferredDate: '',\r\n preferredTime: '',\r\n });\r\n const [errors, setErrors] = useState<Record<string, string>>({});\r\n\r\n const handleSubmit = (e: React.FormEvent) => {\r\n e.preventDefault();\r\n const newErrors: Record<string, string> = {};\r\n\r\n if (!formData.firstName.trim()) {\r\n newErrors.firstName = 'First name is required';\r\n }\r\n if (!formData.lastName.trim()) {\r\n newErrors.lastName = 'Last name is required';\r\n }\r\n if (!formData.email.trim()) {\r\n newErrors.email = 'Email is required';\r\n } else if (!/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(formData.email)) {\r\n newErrors.email = 'Please enter a valid email address';\r\n }\r\n if (!formData.phone.trim()) {\r\n newErrors.phone = 'Phone number is required';\r\n }\r\n\r\n if (Object.keys(newErrors).length > 0) {\r\n setErrors(newErrors);\r\n return;\r\n }\r\n\r\n onSubmit(formData);\r\n };\r\n\r\n const timeSlots = ['Morning (8am - 12pm)', 'Afternoon (12pm - 5pm)', 'Evening (5pm - 8pm)'];\r\n\r\n return (\r\n <motion.div\r\n initial={{ opacity: 0, y: 10 }}\r\n animate={{ opacity: 1, y: 0 }}\r\n className=\"bg-gradient-to-br from-white to-zinc-50 dark:from-zinc-800 dark:to-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-2xl p-6\"\r\n >\r\n <h3 className=\"text-lg text-zinc-900 dark:text-white mb-4\">Talk to AFN Leadership</h3>\r\n\r\n <form onSubmit={handleSubmit} className=\"space-y-3\">\r\n <div>\r\n <input\r\n type=\"text\"\r\n placeholder=\"First Name\"\r\n value={formData.firstName}\r\n onChange={(e) => setFormData({ ...formData, firstName: e.target.value })}\r\n className=\"w-full px-4 py-2.5 bg-white dark:bg-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-lg text-zinc-900 dark:text-white placeholder-zinc-500 focus:border-[#8B5CF6] focus:outline-none transition-colors\"\r\n />\r\n {errors.firstName && <p className=\"text-red-500 text-xs mt-1\">{errors.firstName}</p>}\r\n </div>\r\n\r\n <div>\r\n <input\r\n type=\"text\"\r\n placeholder=\"Last Name\"\r\n value={formData.lastName}\r\n onChange={(e) => setFormData({ ...formData, lastName: e.target.value })}\r\n className=\"w-full px-4 py-2.5 bg-white dark:bg-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-lg text-zinc-900 dark:text-white placeholder-zinc-500 focus:border-[#8B5CF6] focus:outline-none transition-colors\"\r\n />\r\n {errors.lastName && <p className=\"text-red-500 text-xs mt-1\">{errors.lastName}</p>}\r\n </div>\r\n\r\n <div>\r\n <input\r\n type=\"email\"\r\n placeholder=\"Email Address\"\r\n value={formData.email}\r\n onChange={(e) => setFormData({ ...formData, email: e.target.value })}\r\n className=\"w-full px-4 py-2.5 bg-white dark:bg-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-lg text-zinc-900 dark:text-white placeholder-zinc-500 focus:border-[#8B5CF6] focus:outline-none transition-colors\"\r\n />\r\n {errors.email && <p className=\"text-red-500 text-xs mt-1\">{errors.email}</p>}\r\n </div>\r\n\r\n <div>\r\n <input\r\n type=\"tel\"\r\n placeholder=\"Phone Number\"\r\n value={formData.phone}\r\n onChange={(e) => setFormData({ ...formData, phone: e.target.value })}\r\n className=\"w-full px-4 py-2.5 bg-white dark:bg-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-lg text-zinc-900 dark:text-white placeholder-zinc-500 focus:border-[#8B5CF6] focus:outline-none transition-colors\"\r\n />\r\n {errors.phone && <p className=\"text-red-500 text-xs mt-1\">{errors.phone}</p>}\r\n </div>\r\n\r\n <div className=\"pt-2 border-t border-zinc-200 dark:border-zinc-700\">\r\n <p className=\"text-sm text-zinc-600 dark:text-zinc-400 mb-2\">Preferred Call Time (optional)</p>\r\n <div className=\"grid grid-cols-2 gap-2\">\r\n <div className=\"relative\">\r\n <Calendar className=\"pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-zinc-500\" />\r\n <input\r\n type=\"date\"\r\n value={formData.preferredDate}\r\n onChange={(e) => setFormData({ ...formData, preferredDate: e.target.value })}\r\n className=\"w-full pl-12 pr-4 py-2.5 bg-white dark:bg-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-lg text-zinc-900 dark:text-white text-sm focus:border-[#8B5CF6] focus:outline-none transition-colors\"\r\n />\r\n </div>\r\n <div className=\"relative\">\r\n <Clock className=\"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-zinc-500\" />\r\n <select\r\n value={formData.preferredTime}\r\n onChange={(e) => setFormData({ ...formData, preferredTime: e.target.value })}\r\n className=\"w-full pl-10 pr-4 py-2.5 bg-white dark:bg-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-lg text-zinc-900 dark:text-white text-sm focus:border-[#8B5CF6] focus:outline-none transition-colors appearance-none\"\r\n >\r\n <option value=\"\">Select time</option>\r\n {timeSlots.map((slot) => (\r\n <option key={slot} value={slot}>\r\n {slot}\r\n </option>\r\n ))}\r\n </select>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div className=\"flex gap-2 pt-2\">\r\n <button\r\n type=\"submit\"\r\n className=\"flex-1 bg-[#8B5CF6] hover:bg-[#7C3AED] text-white py-2.5 rounded-lg transition-colors\"\r\n >\r\n Request Call\r\n </button>\r\n <button\r\n type=\"button\"\r\n onClick={onCancel}\r\n className=\"px-4 text-zinc-600 dark:text-zinc-400 hover:text-zinc-900 dark:hover:text-white transition-colors\"\r\n >\r\n Cancel\r\n </button>\r\n </div>\r\n </form>\r\n </motion.div>\r\n );\r\n}\r\n\r\n","'use client';\r\n\r\nimport React, { useState } from 'react';\r\nimport { motion } from 'motion/react';\r\n\r\ninterface PersonalizedOverviewFormProps {\r\n onSubmit: (data: {\r\n firstName: string;\r\n lastName: string;\r\n email: string;\r\n phone?: string;\r\n nmlsId?: string;\r\n }) => void;\r\n onCancel: () => void;\r\n}\r\n\r\nexport function PersonalizedOverviewForm({ onSubmit, onCancel }: PersonalizedOverviewFormProps) {\r\n const [formData, setFormData] = useState({\r\n firstName: '',\r\n lastName: '',\r\n email: '',\r\n phone: '',\r\n nmlsId: '',\r\n });\r\n const [errors, setErrors] = useState<Record<string, string>>({});\r\n\r\n const handleSubmit = (e: React.FormEvent) => {\r\n e.preventDefault();\r\n const newErrors: Record<string, string> = {};\r\n\r\n if (!formData.firstName.trim()) {\r\n newErrors.firstName = 'First name is required';\r\n }\r\n if (!formData.lastName.trim()) {\r\n newErrors.lastName = 'Last name is required';\r\n }\r\n if (!formData.email.trim()) {\r\n newErrors.email = 'Email is required';\r\n } else if (!/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(formData.email)) {\r\n newErrors.email = 'Please enter a valid email address';\r\n }\r\n\r\n if (Object.keys(newErrors).length > 0) {\r\n setErrors(newErrors);\r\n return;\r\n }\r\n\r\n onSubmit(formData);\r\n };\r\n\r\n return (\r\n <motion.div\r\n initial={{ opacity: 0, y: 10 }}\r\n animate={{ opacity: 1, y: 0 }}\r\n className=\"bg-gradient-to-br from-white to-zinc-50 dark:from-zinc-800 dark:to-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-2xl p-6\"\r\n >\r\n <h3 className=\"text-lg text-zinc-900 dark:text-white mb-4\">Request Personalized Overview</h3>\r\n\r\n <form onSubmit={handleSubmit} className=\"space-y-3\">\r\n <div>\r\n <input\r\n type=\"text\"\r\n placeholder=\"First Name\"\r\n value={formData.firstName}\r\n onChange={(e) => setFormData({ ...formData, firstName: e.target.value })}\r\n className=\"w-full px-4 py-2.5 bg-white dark:bg-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-lg text-zinc-900 dark:text-white placeholder-zinc-500 focus:border-[#8B5CF6] focus:outline-none transition-colors\"\r\n />\r\n {errors.firstName && <p className=\"text-red-500 text-xs mt-1\">{errors.firstName}</p>}\r\n </div>\r\n\r\n <div>\r\n <input\r\n type=\"text\"\r\n placeholder=\"Last Name\"\r\n value={formData.lastName}\r\n onChange={(e) => setFormData({ ...formData, lastName: e.target.value })}\r\n className=\"w-full px-4 py-2.5 bg-white dark:bg-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-lg text-zinc-900 dark:text-white placeholder-zinc-500 focus:border-[#8B5CF6] focus:outline-none transition-colors\"\r\n />\r\n {errors.lastName && <p className=\"text-red-500 text-xs mt-1\">{errors.lastName}</p>}\r\n </div>\r\n\r\n <div>\r\n <input\r\n type=\"email\"\r\n placeholder=\"Email Address\"\r\n value={formData.email}\r\n onChange={(e) => setFormData({ ...formData, email: e.target.value })}\r\n className=\"w-full px-4 py-2.5 bg-white dark:bg-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-lg text-zinc-900 dark:text-white placeholder-zinc-500 focus:border-[#8B5CF6] focus:outline-none transition-colors\"\r\n />\r\n {errors.email && <p className=\"text-red-500 text-xs mt-1\">{errors.email}</p>}\r\n </div>\r\n\r\n <div>\r\n <input\r\n type=\"tel\"\r\n placeholder=\"Phone (optional)\"\r\n value={formData.phone}\r\n onChange={(e) => setFormData({ ...formData, phone: e.target.value })}\r\n className=\"w-full px-4 py-2.5 bg-white dark:bg-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-lg text-zinc-900 dark:text-white placeholder-zinc-500 focus:border-[#8B5CF6] focus:outline-none transition-colors\"\r\n />\r\n </div>\r\n\r\n <div>\r\n <input\r\n type=\"text\"\r\n placeholder=\"NMLS ID (optional)\"\r\n value={formData.nmlsId}\r\n onChange={(e) => setFormData({ ...formData, nmlsId: e.target.value })}\r\n className=\"w-full px-4 py-2.5 bg-white dark:bg-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-lg text-zinc-900 dark:text-white placeholder-zinc-500 focus:border-[#8B5CF6] focus:outline-none transition-colors\"\r\n />\r\n </div>\r\n\r\n <div className=\"flex gap-2 pt-2\">\r\n <button\r\n type=\"submit\"\r\n className=\"flex-1 bg-[#8B5CF6] hover:bg-[#7C3AED] text-white py-2.5 rounded-lg transition-colors\"\r\n >\r\n Request Overview\r\n </button>\r\n <button\r\n type=\"button\"\r\n onClick={onCancel}\r\n className=\"px-4 text-zinc-600 dark:text-zinc-400 hover:text-zinc-900 dark:hover:text-white transition-colors\"\r\n >\r\n Cancel\r\n </button>\r\n </div>\r\n </form>\r\n </motion.div>\r\n );\r\n}\r\n\r\n","'use client';\r\n\r\nimport { motion } from 'motion/react';\r\n\r\ninterface QuickSuggestion {\r\n text: string;\r\n action: () => void;\r\n}\r\n\r\ninterface QuickSuggestionsProps {\r\n suggestions: QuickSuggestion[];\r\n}\r\n\r\nexport function QuickSuggestions({ suggestions }: QuickSuggestionsProps) {\r\n return (\r\n <motion.div\r\n initial={{ opacity: 0, y: 10 }}\r\n animate={{ opacity: 1, y: 0 }}\r\n className=\"flex flex-wrap gap-2\"\r\n >\r\n {suggestions.map((suggestion, idx) => (\r\n <button\r\n key={idx}\r\n onClick={suggestion.action}\r\n className=\"px-3 py-1.5 bg-zinc-100 dark:bg-zinc-800 hover:bg-zinc-200 dark:hover:bg-zinc-700 text-zinc-700 dark:text-zinc-300 text-sm rounded-full border border-zinc-300 dark:border-zinc-700 transition-colors\"\r\n >\r\n {suggestion.text}\r\n </button>\r\n ))}\r\n </motion.div>\r\n );\r\n}\r\n\r\n","'use client';\r\n\r\nimport { motion } from 'motion/react';\r\n\r\ninterface ModePromptTreeProps {\r\n mode: 'earnings' | 'profit';\r\n step: string;\r\n hasPersonalizedData: boolean;\r\n onResponse: (response: string, data?: any) => void;\r\n}\r\n\r\nexport function ModePromptTree({ mode, step, hasPersonalizedData, onResponse }: ModePromptTreeProps) {\r\n if (mode === 'earnings') {\r\n if (step === 'volume') {\r\n if (hasPersonalizedData) {\r\n return (\r\n <motion.div initial={{ opacity: 0, y: 10 }} animate={{ opacity: 1, y: 0 }} className=\"space-y-3\">\r\n <div className=\"grid grid-cols-1 gap-2\">\r\n <button\r\n onClick={() => onResponse('yes', { volumeMultiplier: 1.0 })}\r\n className=\"px-4 py-3 bg-[#8B5CF6] hover:bg-[#7C3AED] text-white rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Yes, that's about right\r\n </button>\r\n <button\r\n onClick={() => onResponse('higher', { volumeMultiplier: 1.1 })}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n It's a bit higher\r\n </button>\r\n <button\r\n onClick={() => onResponse('lower', { volumeMultiplier: 0.9 })}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n It's a bit lower\r\n </button>\r\n </div>\r\n </motion.div>\r\n );\r\n }\r\n\r\n return (\r\n <motion.div initial={{ opacity: 0, y: 10 }} animate={{ opacity: 1, y: 0 }} className=\"space-y-3\">\r\n <div className=\"grid grid-cols-1 gap-2\">\r\n <button\r\n onClick={() => onResponse('Under $500k', { volume: 400000 })}\r\n className=\"px-4 py-3 bg-[#8B5CF6] hover:bg-[#7C3AED] text-white rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Under $500k\r\n </button>\r\n <button\r\n onClick={() => onResponse('$500k – $1M', { volume: 750000 })}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n $500k – $1M\r\n </button>\r\n <button\r\n onClick={() => onResponse('$1M – $2M', { volume: 1500000 })}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n $1M – $2M\r\n </button>\r\n <button\r\n onClick={() => onResponse('$2M+', { volume: 2500000 })}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n $2M+\r\n </button>\r\n </div>\r\n </motion.div>\r\n );\r\n }\r\n\r\n if (step === 'comp') {\r\n return (\r\n <motion.div initial={{ opacity: 0, y: 10 }} animate={{ opacity: 1, y: 0 }} className=\"space-y-3\">\r\n <div className=\"grid grid-cols-1 gap-2\">\r\n <button\r\n onClick={() => onResponse('Under 100 bps', { comp: 0.95 })}\r\n className=\"px-4 py-3 bg-[#8B5CF6] hover:bg-[#7C3AED] text-white rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Under 100 bps\r\n </button>\r\n <button\r\n onClick={() => onResponse('Around 125 bps', { comp: 1.25 })}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Around 125 bps\r\n </button>\r\n <button\r\n onClick={() => onResponse('150+ bps', { comp: 1.5 })}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n 150+ bps\r\n </button>\r\n <button\r\n onClick={() => onResponse(\"I'm not sure\", { comp: 1.15 })}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n I'm not sure\r\n </button>\r\n </div>\r\n </motion.div>\r\n );\r\n }\r\n\r\n if (step === 'complete') {\r\n return (\r\n <motion.div initial={{ opacity: 0, y: 10 }} animate={{ opacity: 1, y: 0 }} className=\"space-y-3\">\r\n <div className=\"grid grid-cols-1 gap-2\">\r\n <button\r\n onClick={() => onResponse('Talk through this with AFN')}\r\n className=\"px-4 py-3 bg-[#8B5CF6] hover:bg-[#7C3AED] text-white rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Talk through this with AFN\r\n </button>\r\n <button\r\n onClick={() => onResponse('Adjust the numbers')}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Adjust the numbers\r\n </button>\r\n <button\r\n onClick={() => onResponse('Keep exploring')}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Keep exploring\r\n </button>\r\n </div>\r\n </motion.div>\r\n );\r\n }\r\n }\r\n\r\n if (mode === 'profit') {\r\n if (step === 'volume') {\r\n if (hasPersonalizedData) {\r\n return (\r\n <motion.div initial={{ opacity: 0, y: 10 }} animate={{ opacity: 1, y: 0 }} className=\"space-y-3\">\r\n <div className=\"grid grid-cols-1 gap-2\">\r\n <button\r\n onClick={() => onResponse('Yes', { volumeMultiplier: 1.0 })}\r\n className=\"px-4 py-3 bg-[#4399D1] hover:bg-[#2B7AB8] text-white rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Yes\r\n </button>\r\n <button\r\n onClick={() => onResponse('Volume is higher', { volumeMultiplier: 1.1 })}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Volume is higher\r\n </button>\r\n <button\r\n onClick={() => onResponse('Volume is lower', { volumeMultiplier: 0.9 })}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Volume is lower\r\n </button>\r\n </div>\r\n </motion.div>\r\n );\r\n }\r\n\r\n return (\r\n <motion.div initial={{ opacity: 0, y: 10 }} animate={{ opacity: 1, y: 0 }} className=\"space-y-3\">\r\n <div className=\"grid grid-cols-1 gap-2\">\r\n <button\r\n onClick={() => onResponse('Under $100M', { volume: 75000000 })}\r\n className=\"px-4 py-3 bg-[#4399D1] hover:bg-[#2B7AB8] text-white rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Under $100M\r\n </button>\r\n <button\r\n onClick={() => onResponse('$100M – $250M', { volume: 175000000 })}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n $100M – $250M\r\n </button>\r\n <button\r\n onClick={() => onResponse('$250M – $500M', { volume: 375000000 })}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n $250M – $500M\r\n </button>\r\n <button\r\n onClick={() => onResponse('$500M+', { volume: 650000000 })}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n $500M+\r\n </button>\r\n </div>\r\n </motion.div>\r\n );\r\n }\r\n\r\n if (step === 'economics') {\r\n return (\r\n <motion.div initial={{ opacity: 0, y: 10 }} animate={{ opacity: 1, y: 0 }} className=\"space-y-3\">\r\n <div className=\"grid grid-cols-1 gap-2\">\r\n <button\r\n onClick={() => onResponse('Sounds right', { margin: 3.0, grossProfit: 1.5, opEx: 0.75 })}\r\n className=\"px-4 py-3 bg-[#4399D1] hover:bg-[#2B7AB8] text-white rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Sounds right\r\n </button>\r\n <button\r\n onClick={() =>\r\n onResponse('Margin is higher', {\r\n margin: 3.5,\r\n grossProfit: 1.75,\r\n opEx: 0.75,\r\n })\r\n }\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Margin is higher\r\n </button>\r\n <button\r\n onClick={() =>\r\n onResponse('Expenses are higher', {\r\n margin: 3.0,\r\n grossProfit: 1.5,\r\n opEx: 0.95,\r\n })\r\n }\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Expenses are higher\r\n </button>\r\n <button\r\n onClick={() =>\r\n onResponse('Let me adjust', {\r\n margin: 3.0,\r\n grossProfit: 1.5,\r\n opEx: 0.75,\r\n })\r\n }\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Let me adjust\r\n </button>\r\n </div>\r\n </motion.div>\r\n );\r\n }\r\n\r\n if (step === 'complete') {\r\n return (\r\n <motion.div initial={{ opacity: 0, y: 10 }} animate={{ opacity: 1, y: 0 }} className=\"space-y-3\">\r\n <div className=\"grid grid-cols-1 gap-2\">\r\n <button\r\n onClick={() => onResponse('Sanity-check with AFN')}\r\n className=\"px-4 py-3 bg-[#4399D1] hover:bg-[#2B7AB8] text-white rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Sanity-check with AFN\r\n </button>\r\n <button\r\n onClick={() => onResponse('Adjust assumptions')}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Adjust assumptions\r\n </button>\r\n <button\r\n onClick={() => onResponse('Schedule leadership call')}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Schedule leadership call\r\n </button>\r\n </div>\r\n </motion.div>\r\n );\r\n }\r\n }\r\n\r\n return null;\r\n}\r\n\r\n","import React, { useState } from 'react';\r\n\r\nconst ERROR_IMG_SRC =\r\n 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iODgiIGhlaWdodD0iODgiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBvcGFjaXR5PSIuMyIgZmlsbD0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIzLjciPjxyZWN0IHg9IjE2IiB5PSIxNiIgd2lkdGg9IjU2IiBoZWlnaHQ9IjU2IiByeD0iNiIvPjxwYXRoIGQ9Im0xNiA1OCAxNi0xOCAzMiAzMiIvPjxjaXJjbGUgY3g9IjUzIiBjeT0iMzUiIHI9IjciLz48L3N2Zz4KCg==';\r\n\r\nexport function ImageWithFallback(props: React.ImgHTMLAttributes<HTMLImageElement>) {\r\n const [didError, setDidError] = useState(false);\r\n\r\n const handleError = () => {\r\n setDidError(true);\r\n };\r\n\r\n const { src, alt, style, className, ...rest } = props;\r\n\r\n return didError ? (\r\n <div\r\n className={`inline-block bg-gray-100 text-center align-middle ${className ?? ''}`}\r\n style={style}\r\n >\r\n <div className=\"flex items-center justify-center w-full h-full\">\r\n <img src={ERROR_IMG_SRC} alt=\"Error loading image\" {...rest} data-original-url={src} />\r\n </div>\r\n </div>\r\n ) : (\r\n <img src={src} alt={alt} className={className} style={style} {...rest} onError={handleError} />\r\n );\r\n}\r\n\r\n"],"mappings":"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","names":["import_react","import_lucide_react","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_jsx_runtime"]}
package/dist/index.mjs CHANGED
@@ -4,7 +4,7 @@ import { jsx } from "react/jsx-runtime";
4
4
  var BradyChatContext = createContext(void 0);
5
5
  var initialMessages = [
6
6
  {
7
- type: "brady",
7
+ type: "user",
8
8
  text: "introduce"
9
9
  }
10
10
  ];
@@ -1168,36 +1168,7 @@ I'll focus on ways to increase ${isBranchManager ? "profit" : "income"} using ${
1168
1168
  action: () => handleQuickSuggestion(s.prompt)
1169
1169
  }));
1170
1170
  }
1171
- return [
1172
- {
1173
- text: "How does AFN help LOs grow?",
1174
- action: () => handleQuickSuggestion("How does AFN help LOs grow?")
1175
- },
1176
- {
1177
- text: "How does AFN help branch managers earn more?",
1178
- action: () => handleQuickSuggestion("How does AFN help branch managers earn more?")
1179
- },
1180
- {
1181
- text: "Why do people choose AFN?",
1182
- action: () => handleQuickSuggestion("Why do people choose AFN?")
1183
- },
1184
- {
1185
- text: "The AFN Advantage",
1186
- action: () => handleQuickSuggestion("See How AFN Supports Loan Officer Success")
1187
- },
1188
- {
1189
- text: "Why AFN?",
1190
- action: () => handleQuickSuggestion("Why AFN?")
1191
- },
1192
- {
1193
- text: "How does AI help me earn more?",
1194
- action: () => handleQuickSuggestion("How does AI help me earn more?")
1195
- },
1196
- {
1197
- text: "What makes AFN different?",
1198
- action: () => handleQuickSuggestion("What makes AFN different?")
1199
- }
1200
- ];
1171
+ return [];
1201
1172
  };
1202
1173
  const initialSuggestions = buildSuggestions();
1203
1174
  const postSubmitSuggestions = buildSuggestions();
@@ -1220,9 +1191,6 @@ I'll focus on ways to increase ${isBranchManager ? "profit" : "income"} using ${
1220
1191
  }
1221
1192
  ) : null;
1222
1193
  if (isHidden) return null;
1223
- if (!bradyHealthy) {
1224
- return /* @__PURE__ */ jsx8("div", { className: "fixed top-0 right-0 w-full md:w-[360px] h-screen flex flex-col bg-gradient-to-br dark:from-zinc-900 dark:to-zinc-800 from-white to-zinc-50 border-l md:border-l dark:border-zinc-700 border-zinc-300 shadow-2xl z-[100] overflow-hidden transition-all duration-300 items-center justify-center", children: /* @__PURE__ */ jsx8("div", { className: "text-center text-zinc-500 dark:text-zinc-400 text-lg font-medium", children: "Sorry, Brady AI is currently unavailable." }) });
1225
- }
1226
1194
  return /* @__PURE__ */ jsxs5("div", { className: "fixed top-0 right-0 w-full md:w-[360px] h-screen flex flex-col bg-gradient-to-br dark:from-zinc-900 dark:to-zinc-800 from-white to-zinc-50 border-l md:border-l dark:border-zinc-700 border-zinc-300 shadow-2xl z-[100] overflow-hidden transition-all duration-300", children: [
1227
1195
  /* @__PURE__ */ jsxs5("div", { className: "flex items-center justify-between px-4 py-3 border-b dark:border-zinc-800 border-zinc-200 dark:bg-zinc-950/80 bg-white/95 backdrop-blur-lg", children: [
1228
1196
  /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-3", children: [
@@ -1290,6 +1258,7 @@ I'll focus on ways to increase ${isBranchManager ? "profit" : "income"} using ${
1290
1258
  ] })
1291
1259
  ] }),
1292
1260
  modeBadge && /* @__PURE__ */ jsx8("div", { className: "px-4 py-2 border-b dark:border-zinc-800 border-zinc-200", children: modeBadge }),
1261
+ !bradyHealthy && /* @__PURE__ */ jsx8("div", { className: "fixed top-0 right-0 w-full md:w-[360px] h-screen flex flex-col bg-gradient-to-br dark:from-zinc-900 dark:to-zinc-800 from-white to-zinc-50 border-l md:border-l dark:border-zinc-700 border-zinc-300 shadow-2xl z-[100] overflow-hidden transition-all duration-300 items-center justify-center", children: /* @__PURE__ */ jsx8("div", { className: "text-center text-zinc-500 dark:text-zinc-400 text-lg font-medium", children: "Sorry, Brady AI is currently unavailable." }) }),
1293
1262
  /* @__PURE__ */ jsxs5("div", { className: "flex-1 overflow-y-auto p-4 space-y-4", children: [
1294
1263
  /* @__PURE__ */ jsx8(AnimatePresence, { children: messages.map((msg, idx) => /* @__PURE__ */ jsx8(
1295
1264
  motion6.div,
@@ -1301,7 +1270,7 @@ I'll focus on ways to increase ${isBranchManager ? "profit" : "income"} using ${
1301
1270
  "div",
1302
1271
  {
1303
1272
  className: `px-4 py-3 rounded-2xl whitespace-pre-line ${msg.type === "user" ? "bg-[#8B5CF6] text-white rounded-br-sm" : "dark:bg-zinc-800 bg-zinc-100 dark:text-zinc-100 text-zinc-900 rounded-bl-sm"}`,
1304
- children: msg.text
1273
+ children: msg.text === "introduce" ? "" : msg.text
1305
1274
  }
1306
1275
  )
1307
1276
  },
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/lib/BradyChatContext.tsx","../src/lib/EnhancedBradyChat.tsx","../src/lib/api/afnBradyApi.ts","../src/lib/api/bradyHealth.ts","../src/lib/InfoRequestForm.tsx","../src/lib/LeadershipCallForm.tsx","../src/lib/PersonalizedOverviewForm.tsx","../src/lib/QuickSuggestions.tsx","../src/lib/ModePromptTree.tsx","../src/lib/ImageWithFallback.tsx"],"sourcesContent":["'use client';\r\n\r\nimport React, { createContext, useContext, useState, ReactNode } from 'react';\r\n\r\nexport type ChatWorkflowType =\r\n | 'free'\r\n | 'info-request'\r\n | 'leadership-call'\r\n | 'personalized-overview-request'\r\n | 'earnings-mode'\r\n | 'profit-mode';\r\nexport type ModeType = 'none' | 'earnings' | 'profit';\r\nexport type ModeStep = 'initial' | 'volume' | 'comp' | 'economics' | 'calculator' | 'complete';\r\n\r\nexport interface ChatMessage {\r\n type: 'user' | 'brady' | 'form';\r\n text?: string;\r\n component?: ReactNode;\r\n}\r\n\r\ninterface ModeData {\r\n volume?: number;\r\n comp?: number;\r\n margin?: number;\r\n grossProfit?: number;\r\n opEx?: number;\r\n volumeMultiplier?: number;\r\n}\r\n\r\ninterface BradyChatContextType {\r\n workflowType: ChatWorkflowType;\r\n messages: ChatMessage[];\r\n startWorkflow: (workflow: ChatWorkflowType) => void;\r\n addMessage: (message: ChatMessage) => void;\r\n setWorkflow: (workflow: ChatWorkflowType) => void;\r\n resetChat: () => void;\r\n // Mode system\r\n activeMode: ModeType;\r\n modeStep: ModeStep;\r\n modeData: ModeData;\r\n activateMode: (mode: ModeType) => void;\r\n setModeStep: (step: ModeStep) => void;\r\n updateModeData: (data: Partial<ModeData>) => void;\r\n resetMode: () => void;\r\n // Calculator control\r\n calculatorOpen: boolean;\r\n setCalculatorOpen: (open: boolean) => void;\r\n isHidden: boolean;\r\n setIsHidden: React.Dispatch<React.SetStateAction<boolean>>;\r\n // Modal-aware Brady AI\r\n hideBradyForModal: () => void;\r\n restoreBradyAfterModal: () => void;\r\n}\r\n\r\nconst BradyChatContext = createContext<BradyChatContextType | undefined>(undefined);\r\n\r\nconst initialMessages: ChatMessage[] = [\r\n {\r\n type: 'brady',\r\n text: \"introduce\",\r\n },\r\n];\r\n\r\nexport function BradyChatProvider({ children }: { children: ReactNode }) {\r\n const [workflowType, setWorkflowType] = useState<ChatWorkflowType>('free');\r\n const [messages, setMessages] = useState<ChatMessage[]>(initialMessages);\r\n // Mode system state\r\n const [activeMode, setActiveMode] = useState<ModeType>('none');\r\n const [modeStep, setModeStep] = useState<ModeStep>('initial');\r\n const [modeData, setModeData] = useState<ModeData>({});\r\n const [calculatorOpen, setCalculatorOpen] = useState(false);\r\n // Global hide/show state for Brady chat (default hidden)\r\n const [isHidden, setIsHidden] = useState(true);\r\n // Track previous visibility for modal\r\n const [wasBradyVisibleBeforeModal, setWasBradyVisibleBeforeModal] = useState(false);\r\n\r\n // Modal-aware hide/show\r\n const hideBradyForModal = () => {\r\n setWasBradyVisibleBeforeModal(!isHidden);\r\n setIsHidden(true);\r\n };\r\n const restoreBradyAfterModal = () => {\r\n if (wasBradyVisibleBeforeModal) setIsHidden(false);\r\n };\r\n\r\n const startWorkflow = (workflow: ChatWorkflowType) => {\r\n setWorkflowType(workflow);\r\n\r\n // Set appropriate initial message based on workflow\r\n if (workflow === 'info-request') {\r\n setMessages([\r\n {\r\n type: 'brady',\r\n text: \"Happy to send you a personalized overview.\\n\\nIf you share your contact details below, we'll email you more information about AFN and how it could fit your goals.\",\r\n },\r\n ]);\r\n } else if (workflow === 'leadership-call') {\r\n setMessages([\r\n {\r\n type: 'brady',\r\n text: \"Happy to connect you with AFN leadership.\\n\\nShare your details below and we'll have someone reach out shortly.\\nIf you'd like, you can also suggest a good time to talk.\",\r\n },\r\n ]);\r\n } else if (workflow === 'personalized-overview-request') {\r\n setMessages([\r\n {\r\n type: 'brady',\r\n text: \"I'll help you get a personalized dashboard and earnings calculator.\\n\\nShare your details below and we'll create a custom overview showing exactly what your business could look like at AFN.\",\r\n },\r\n ]);\r\n } else {\r\n setMessages(initialMessages);\r\n }\r\n };\r\n\r\n const addMessage = (message: ChatMessage) => {\r\n setMessages((prev) => [...prev, message]);\r\n };\r\n\r\n const setWorkflow = (workflow: ChatWorkflowType) => {\r\n setWorkflowType(workflow);\r\n };\r\n\r\n const resetChat = () => {\r\n setWorkflowType('free');\r\n setMessages(initialMessages);\r\n resetMode();\r\n };\r\n\r\n // Mode system functions\r\n const activateMode = (mode: ModeType) => {\r\n setActiveMode(mode);\r\n setModeStep('initial');\r\n setModeData({});\r\n\r\n // Set initial mode message\r\n if (mode === 'earnings') {\r\n setMessages([\r\n {\r\n type: 'brady',\r\n text: \"Earnings Mode is on.\\n\\nI'll focus on how volume, efficiency, and time savings can impact your income.\",\r\n },\r\n ]);\r\n setModeStep('volume');\r\n } else if (mode === 'profit') {\r\n setMessages([\r\n {\r\n type: 'brady',\r\n text: 'Profit Mode is on.\\n\\nI\\'ll focus on branch economics—volume, margin, expenses, and profitability.',\r\n },\r\n ]);\r\n setModeStep('volume');\r\n }\r\n };\r\n\r\n const updateModeData = (data: Partial<ModeData>) => {\r\n setModeData((prev) => ({ ...prev, ...data }));\r\n };\r\n\r\n const resetMode = () => {\r\n setActiveMode('none');\r\n setModeStep('initial');\r\n setModeData({});\r\n setCalculatorOpen(false);\r\n };\r\n\r\n return (\r\n <BradyChatContext.Provider\r\n value={{\r\n workflowType,\r\n messages,\r\n startWorkflow,\r\n addMessage,\r\n setWorkflow,\r\n resetChat,\r\n activeMode,\r\n modeStep,\r\n modeData,\r\n activateMode,\r\n setModeStep,\r\n updateModeData,\r\n resetMode,\r\n calculatorOpen,\r\n setCalculatorOpen,\r\n isHidden,\r\n setIsHidden,\r\n hideBradyForModal,\r\n restoreBradyAfterModal,\r\n }}\r\n >\r\n {children}\r\n </BradyChatContext.Provider>\r\n );\r\n}\r\n\r\nexport function useBradyChat() {\r\n const context = useContext(BradyChatContext);\r\n if (context === undefined) {\r\n throw new Error('useBradyChat must be used within a BradyChatProvider');\r\n }\r\n return context;\r\n}\r\n\r\n","'use client';\r\n\r\nimport { useState, useRef, useEffect } from 'react';\r\nimport { motion, AnimatePresence } from 'motion/react';\r\nimport { Send, Mic } from 'lucide-react';\r\n\r\nimport { checkBradyHealth } from './api/bradyHealth';\r\nimport { sendBradyPrompt } from './api/afnBradyApi';\r\nimport { useBradyChat } from './BradyChatContext';\r\nimport { InfoRequestForm } from './InfoRequestForm';\r\nimport { LeadershipCallForm } from './LeadershipCallForm';\r\nimport { PersonalizedOverviewForm } from './PersonalizedOverviewForm';\r\nimport { QuickSuggestions } from './QuickSuggestions';\r\nimport { ModePromptTree } from './ModePromptTree';\r\nimport { ImageWithFallback } from './ImageWithFallback';\r\n\r\ntype ModeVariant = 'loan-officer' | 'branch-manager';\r\n\r\nexport interface EnhancedBradyChatProps {\r\n /**\r\n * Controls whether the mode toggle uses Earnings (LO) or Profit (branch manager) language.\r\n * Defaults to 'loan-officer'.\r\n */\r\n modeVariant?: ModeVariant;\r\n /**\r\n * Avatar image URL for Brady.\r\n * Typically you pass something like `/bradyIcon.png` from your app's public assets.\r\n */\r\n avatarSrc: string;\r\n}\r\n\r\nexport function EnhancedBradyChat({ modeVariant = 'loan-officer', avatarSrc }: EnhancedBradyChatProps) {\r\n const [bradyHealthy, setBradyHealthy] = useState(true);\r\n const {\r\n workflowType,\r\n messages,\r\n addMessage,\r\n resetChat,\r\n setWorkflow,\r\n activeMode,\r\n modeStep,\r\n modeData,\r\n setModeStep,\r\n updateModeData,\r\n setCalculatorOpen,\r\n activateMode,\r\n resetMode,\r\n isHidden,\r\n setIsHidden,\r\n } = useBradyChat();\r\n const [inputValue, setInputValue] = useState('');\r\n const [showForm, setShowForm] = useState(false);\r\n const [inputDisabled, setInputDisabled] = useState(false);\r\n const [showModePrompts, setShowModePrompts] = useState(false);\r\n const messagesEndRef = useRef<HTMLDivElement>(null);\r\n const [suggestionLinks, setSuggestionLinks] = useState<{ text: string; prompt: string }[] | null>(null);\r\n\r\n const isBranchManager = modeVariant === 'branch-manager';\r\n const pageMode = isBranchManager ? 'profit' : 'earnings';\r\n const isModeActive = activeMode === pageMode;\r\n const hasPersonalizedData = false;\r\n\r\n const handleFocusToggle = () => {\r\n if (isModeActive) {\r\n resetMode();\r\n } else {\r\n activateMode(pageMode);\r\n setTimeout(() => {\r\n addMessage({\r\n type: 'brady',\r\n text: `${\r\n isBranchManager ? 'Profit' : 'Earnings'\r\n } Mode is on.\\n\\nI'll focus on ways to increase ${\r\n isBranchManager ? 'profit' : 'income'\r\n } using ${\r\n isBranchManager\r\n ? 'branch economics, recruiting leverage, and operational efficiency'\r\n : 'volume, efficiency, and time savings'\r\n }.`,\r\n });\r\n }, 300);\r\n }\r\n };\r\n\r\n useEffect(() => {\r\n let mounted = true;\r\n const checkHealth = async () => {\r\n const healthy = await checkBradyHealth();\r\n if (mounted) setBradyHealthy(healthy);\r\n };\r\n checkHealth();\r\n const interval = setInterval(checkHealth, 60000);\r\n return () => {\r\n mounted = false;\r\n clearInterval(interval);\r\n };\r\n }, []);\r\n\r\n useEffect(() => {\r\n if (\r\n workflowType === 'info-request' ||\r\n workflowType === 'leadership-call' ||\r\n workflowType === 'personalized-overview-request'\r\n ) {\r\n setShowForm(true);\r\n setInputDisabled(true);\r\n setShowModePrompts(false);\r\n } else {\r\n setShowForm(false);\r\n setInputDisabled(false);\r\n }\r\n }, [workflowType]);\r\n\r\n useEffect(() => {\r\n if (activeMode !== 'none' && modeStep === 'volume') {\r\n setShowModePrompts(true);\r\n\r\n if (activeMode === 'earnings') {\r\n if (hasPersonalizedData) {\r\n setTimeout(() => {\r\n addMessage({\r\n type: 'brady',\r\n text: 'I have an estimate of your recent production.\\nDoes this feel close?',\r\n });\r\n }, 500);\r\n } else {\r\n setTimeout(() => {\r\n addMessage({\r\n type: 'brady',\r\n text: 'To keep this realistic, about how much volume do you fund in an average month?',\r\n });\r\n }, 500);\r\n }\r\n } else if (activeMode === 'profit') {\r\n if (hasPersonalizedData) {\r\n setTimeout(() => {\r\n addMessage({\r\n type: 'brady',\r\n text: 'I have a baseline view of your branch.\\nDoes this feel directionally right?',\r\n });\r\n }, 500);\r\n } else {\r\n setTimeout(() => {\r\n addMessage({\r\n type: 'brady',\r\n text: 'To start, about how much volume does your branch fund annually?',\r\n });\r\n }, 500);\r\n }\r\n }\r\n }\r\n }, [activeMode, modeStep, addMessage]);\r\n\r\n useEffect(() => {\r\n scrollToBottom();\r\n }, [messages, showForm, showModePrompts]);\r\n\r\n const scrollToBottom = () => {\r\n messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });\r\n };\r\n\r\n const handleModeResponse = (response: string, data?: any) => {\r\n addMessage({ type: 'user', text: response });\r\n setShowModePrompts(false);\r\n\r\n if (data) {\r\n updateModeData(data);\r\n }\r\n\r\n if (activeMode === 'earnings') {\r\n if (modeStep === 'volume') {\r\n setTimeout(() => {\r\n addMessage({\r\n type: 'brady',\r\n text: 'And roughly how do you get paid today?',\r\n });\r\n setModeStep('comp');\r\n setShowModePrompts(true);\r\n }, 800);\r\n } else if (modeStep === 'comp') {\r\n setTimeout(() => {\r\n addMessage({\r\n type: 'brady',\r\n text: \"Got it. I'll pull this together so you can see it clearly.\",\r\n });\r\n setModeStep('calculator');\r\n setTimeout(() => {\r\n setCalculatorOpen(true);\r\n setModeStep('complete');\r\n setTimeout(() => {\r\n addMessage({\r\n type: 'brady',\r\n text: 'Want to sanity-check these assumptions together?',\r\n });\r\n setShowModePrompts(true);\r\n }, 1000);\r\n }, 800);\r\n }, 800);\r\n } else if (modeStep === 'complete') {\r\n if (response.includes('Talk through')) {\r\n setShowModePrompts(false);\r\n setTimeout(() => {\r\n startWorkflow('leadership-call');\r\n }, 500);\r\n } else if (response.includes('Adjust')) {\r\n setShowModePrompts(false);\r\n setTimeout(() => {\r\n setCalculatorOpen(true);\r\n }, 500);\r\n } else {\r\n setShowModePrompts(false);\r\n setTimeout(() => {\r\n addMessage({\r\n type: 'brady',\r\n text: \"I'm here whenever you need me. What else would you like to explore?\",\r\n });\r\n }, 800);\r\n }\r\n }\r\n } else if (activeMode === 'profit') {\r\n if (modeStep === 'volume') {\r\n setTimeout(() => {\r\n addMessage({\r\n type: 'brady',\r\n text:\r\n \"For modeling, I'll assume:\\n• ~300 bps branch margin\\n• ~150 bps gross profit\\n\" +\r\n '• ~75 bps operating expenses\\n\\nWe can adjust all of this.',\r\n });\r\n setModeStep('economics');\r\n setShowModePrompts(true);\r\n }, 800);\r\n } else if (modeStep === 'economics') {\r\n setTimeout(() => {\r\n addMessage({\r\n type: 'brady',\r\n text: \"Here's a clean P&L view based on what we discussed.\",\r\n });\r\n setModeStep('calculator');\r\n setTimeout(() => {\r\n setCalculatorOpen(true);\r\n setModeStep('complete');\r\n setTimeout(() => {\r\n addMessage({\r\n type: 'brady',\r\n text: \"Want help building a realistic pro forma based on AFN's structure?\",\r\n });\r\n setShowModePrompts(true);\r\n }, 1000);\r\n }, 800);\r\n }, 800);\r\n } else if (modeStep === 'complete') {\r\n if (response.includes('Sanity-check') || response.includes('leadership')) {\r\n setShowModePrompts(false);\r\n setTimeout(() => {\r\n startWorkflow('leadership-call');\r\n }, 500);\r\n } else if (response.includes('Adjust')) {\r\n setShowModePrompts(false);\r\n setTimeout(() => {\r\n setCalculatorOpen(true);\r\n }, 500);\r\n }\r\n }\r\n }\r\n };\r\n\r\n const handleSend = async () => {\r\n if (inputValue.trim() && !inputDisabled) {\r\n const userText = inputValue;\r\n addMessage({ type: 'user', text: userText });\r\n setInputValue('');\r\n try {\r\n const apiResponse = await sendBradyPrompt([{ role: 'user', content: userText }]);\r\n let mappedType: 'user' | 'brady' | 'form' = 'brady';\r\n if (apiResponse.role === 'user') mappedType = 'user';\r\n addMessage({ type: mappedType, text: apiResponse.content });\r\n } catch {\r\n addMessage({ type: 'brady', text: 'Sorry, Brady AI is currently unavailable.' });\r\n }\r\n }\r\n };\r\n\r\n const handleQuickSuggestion = async (text: string) => {\r\n addMessage({ type: 'user', text });\r\n try {\r\n const apiResponse = await sendBradyPrompt([{ role: 'user', content: text }]);\r\n\r\n if (Array.isArray(apiResponse.suggestionLink)) {\r\n setSuggestionLinks(apiResponse.suggestionLink);\r\n }\r\n\r\n let mappedType: 'user' | 'brady' | 'form' = 'brady';\r\n if (apiResponse.role === 'user') mappedType = 'user';\r\n addMessage({ type: mappedType, text: apiResponse.content });\r\n } catch {\r\n addMessage({ type: 'brady', text: 'Sorry, Brady AI is currently unavailable.' });\r\n }\r\n };\r\n\r\n const handleInfoFormSubmit = (data: any) => {\r\n addMessage({\r\n type: 'brady',\r\n text:\r\n \"Got it — thanks.\\n\\nWe'll email you a personalized overview shortly.\\nIf you have questions in the meantime, I'm here to help.\",\r\n });\r\n setShowForm(false);\r\n setInputDisabled(false);\r\n setWorkflow('free');\r\n };\r\n\r\n const handleLeadershipFormSubmit = (data: any) => {\r\n addMessage({\r\n type: 'brady',\r\n text:\r\n \"Thanks — you're all set.\\n\\nSomeone from AFN leadership will reach out shortly to connect.\\nIn the meantime, feel free to ask me anything.\",\r\n });\r\n setShowForm(false);\r\n setInputDisabled(false);\r\n setWorkflow('free');\r\n };\r\n\r\n const handlePersonalizedOverviewFormSubmit = (data: any) => {\r\n addMessage({\r\n type: 'brady',\r\n text:\r\n \"Perfect — thanks!\\n\\nWe'll create a personalized dashboard and earnings calculator based on your information and send it to you shortly.\\n\\nYou'll be able to see exactly what your business could look like at AFN with specific projections tailored to your situation.\",\r\n });\r\n setShowForm(false);\r\n setInputDisabled(false);\r\n setWorkflow('free');\r\n };\r\n\r\n const handleFormCancel = () => {\r\n setShowForm(false);\r\n setInputDisabled(false);\r\n resetChat();\r\n };\r\n\r\n const buildSuggestions = () => {\r\n if (suggestionLinks && suggestionLinks.length > 0) {\r\n return suggestionLinks.map((s) => ({\r\n text: s.text,\r\n action: () => handleQuickSuggestion(s.prompt),\r\n }));\r\n }\r\n return [\r\n {\r\n text: 'How does AFN help LOs grow?',\r\n action: () => handleQuickSuggestion('How does AFN help LOs grow?'),\r\n },\r\n {\r\n text: 'How does AFN help branch managers earn more?',\r\n action: () => handleQuickSuggestion('How does AFN help branch managers earn more?'),\r\n },\r\n {\r\n text: 'Why do people choose AFN?',\r\n action: () => handleQuickSuggestion('Why do people choose AFN?'),\r\n },\r\n {\r\n text: 'The AFN Advantage',\r\n action: () => handleQuickSuggestion('See How AFN Supports Loan Officer Success'),\r\n },\r\n {\r\n text: 'Why AFN?',\r\n action: () => handleQuickSuggestion('Why AFN?'),\r\n },\r\n {\r\n text: 'How does AI help me earn more?',\r\n action: () => handleQuickSuggestion('How does AI help me earn more?'),\r\n },\r\n {\r\n text: 'What makes AFN different?',\r\n action: () => handleQuickSuggestion('What makes AFN different?'),\r\n },\r\n ];\r\n };\r\n\r\n const initialSuggestions = buildSuggestions();\r\n const postSubmitSuggestions = buildSuggestions();\r\n\r\n const showPostSubmitSuggestions = messages.length > 2 && !showForm && workflowType === 'free' && activeMode === 'none';\r\n\r\n const startWorkflow = (workflow: any) => {\r\n setWorkflow(workflow);\r\n if (workflow === 'info-request') {\r\n setShowForm(true);\r\n setInputDisabled(true);\r\n } else if (workflow === 'leadership-call') {\r\n setShowForm(true);\r\n setInputDisabled(true);\r\n }\r\n };\r\n\r\n const modeBadge =\r\n activeMode !== 'none' ? (\r\n <div\r\n className={`px-3 py-1 rounded-full text-xs font-medium ${\r\n activeMode === 'earnings'\r\n ? 'bg-[#8B5CF6]/20 text-[#8B5CF6] border border-[#8B5CF6]/30'\r\n : 'bg-[#4399D1]/20 text-[#4399D1] border border-[#4399D1]/30'\r\n }`}\r\n >\r\n {activeMode === 'earnings' ? 'Earnings Mode' : 'Profit Mode'}\r\n </div>\r\n ) : null;\r\n\r\n if (isHidden) return null;\r\n if (!bradyHealthy) {\r\n return (\r\n <div className=\"fixed top-0 right-0 w-full md:w-[360px] h-screen flex flex-col bg-gradient-to-br dark:from-zinc-900 dark:to-zinc-800 from-white to-zinc-50 border-l md:border-l dark:border-zinc-700 border-zinc-300 shadow-2xl z-[100] overflow-hidden transition-all duration-300 items-center justify-center\">\r\n <div className=\"text-center text-zinc-500 dark:text-zinc-400 text-lg font-medium\">\r\n Sorry, Brady AI is currently unavailable.\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className=\"fixed top-0 right-0 w-full md:w-[360px] h-screen flex flex-col bg-gradient-to-br dark:from-zinc-900 dark:to-zinc-800 from-white to-zinc-50 border-l md:border-l dark:border-zinc-700 border-zinc-300 shadow-2xl z-[100] overflow-hidden transition-all duration-300\">\r\n <div className=\"flex items-center justify-between px-4 py-3 border-b dark:border-zinc-800 border-zinc-200 dark:bg-zinc-950/80 bg-white/95 backdrop-blur-lg\">\r\n <div className=\"flex items-center gap-3\">\r\n <div className=\"relative\">\r\n <span className=\"relative w-10 h-10 block group\">\r\n <span\r\n className={`absolute inset-0 rounded-full transition-colors duration-300 ${\r\n bradyHealthy ? 'dark:bg-zinc-700/40 bg-transparent' : 'bg-red-600/80 dark:bg-red-700/80'\r\n }`}\r\n ></span>\r\n <ImageWithFallback\r\n src={avatarSrc}\r\n alt=\"Brady AI\"\r\n className=\"w-10 h-10 relative z-10\"\r\n onClick={() => setIsHidden(true)}\r\n />\r\n </span>\r\n </div>\r\n <div className=\"dark:text-white text-zinc-900\">Brady AI</div>\r\n </div>\r\n\r\n <div className=\"relative inline-flex items-center h-[34px] w-[150px] dark:bg-zinc-800/50 bg-zinc-200 rounded-full p-1\">\r\n <button\r\n onClick={() => isModeActive && resetMode()}\r\n className={`relative z-10 flex-1 h-full rounded-full text-[11px] tracking-wide uppercase font-medium transition-all duration-300 flex items-center justify-center ${\r\n !isModeActive\r\n ? 'text-white'\r\n : 'dark:text-zinc-500 text-zinc-600 hover:dark:bg-zinc-700/50 hover:bg-zinc-300/50'\r\n }`}\r\n >\r\n NORMAL\r\n </button>\r\n\r\n <div className=\"relative flex-1\">\r\n {!isModeActive && (\r\n <div\r\n className=\"absolute inset-0 rounded-full animate-pulse\"\r\n style={{\r\n boxShadow: isBranchManager\r\n ? '0 0 16px rgba(67, 153, 209, 0.6), inset 0 0 10px rgba(67, 153, 209, 0.3)'\r\n : '0 0 16px rgba(139, 92, 246, 0.6), inset 0 0 10px rgba(139, 92, 246, 0.3)',\r\n animation: 'pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite',\r\n }}\r\n />\r\n )}\r\n <button\r\n onClick={() => !isModeActive && handleFocusToggle()}\r\n className={`relative z-10 w-full h-full rounded-full text-[11px] tracking-wide uppercase font-medium transition-all duration-300 flex items-center justify-center ${\r\n isModeActive\r\n ? 'text-white'\r\n : 'dark:text-zinc-500 text-zinc-600 hover:dark:bg-zinc-700/50 hover:bg-zinc-300/50'\r\n }`}\r\n >\r\n {isBranchManager ? 'PROFIT' : 'EARNINGS'}\r\n </button>\r\n </div>\r\n\r\n <div\r\n className={`absolute top-1 bottom-1 rounded-full transition-all duration-300 ${\r\n isModeActive ? 'left-[50%] right-1' : 'left-1 right-[50%]'\r\n }`}\r\n style={\r\n isModeActive\r\n ? {\r\n background: isBranchManager\r\n ? 'linear-gradient(135deg, #4399D1 0%, #3b82d9 100%)'\r\n : 'linear-gradient(135deg, #8B5CF6 0%, #7C3AED 100%)',\r\n boxShadow: isBranchManager\r\n ? '0 0 16px rgba(67, 153, 209, 0.15)'\r\n : '0 0 16px rgba(139, 92, 246, 0.15)',\r\n }\r\n : {\r\n background: 'var(--tw-gradient-stops)',\r\n backgroundImage: 'linear-gradient(135deg, rgb(82, 82, 91) 0%, rgb(63, 63, 70) 100%)',\r\n }\r\n }\r\n />\r\n </div>\r\n </div>\r\n\r\n {modeBadge && (\r\n <div className=\"px-4 py-2 border-b dark:border-zinc-800 border-zinc-200\">\r\n {modeBadge}\r\n </div>\r\n )}\r\n\r\n <div className=\"flex-1 overflow-y-auto p-4 space-y-4\">\r\n <AnimatePresence>\r\n {messages.map((msg, idx) => (\r\n <motion.div\r\n key={idx}\r\n initial={{ opacity: 0, y: 10 }}\r\n animate={{ opacity: 1, y: 0 }}\r\n className={`flex ${msg.type === 'user' ? 'justify-end' : 'justify-start'}`}\r\n >\r\n <div\r\n className={`px-4 py-3 rounded-2xl whitespace-pre-line ${\r\n msg.type === 'user'\r\n ? 'bg-[#8B5CF6] text-white rounded-br-sm'\r\n : 'dark:bg-zinc-800 bg-zinc-100 dark:text-zinc-100 text-zinc-900 rounded-bl-sm'\r\n }`}\r\n >\r\n {msg.text}\r\n </div>\r\n </motion.div>\r\n ))}\r\n </AnimatePresence>\r\n\r\n {showForm && workflowType === 'info-request' && (\r\n <InfoRequestForm onSubmit={handleInfoFormSubmit} onCancel={handleFormCancel} />\r\n )}\r\n\r\n {showForm && workflowType === 'leadership-call' && (\r\n <LeadershipCallForm onSubmit={handleLeadershipFormSubmit} onCancel={handleFormCancel} />\r\n )}\r\n\r\n {showForm && workflowType === 'personalized-overview-request' && (\r\n <PersonalizedOverviewForm\r\n onSubmit={handlePersonalizedOverviewFormSubmit}\r\n onCancel={handleFormCancel}\r\n />\r\n )}\r\n\r\n {showModePrompts && activeMode !== 'none' && (\r\n <ModePromptTree\r\n mode={activeMode as 'earnings' | 'profit'}\r\n step={modeStep}\r\n hasPersonalizedData={hasPersonalizedData}\r\n onResponse={handleModeResponse}\r\n />\r\n )}\r\n\r\n {!showForm &&\r\n !showModePrompts &&\r\n messages.length === 1 &&\r\n workflowType === 'free' &&\r\n activeMode === 'none' && <QuickSuggestions suggestions={initialSuggestions} />}\r\n\r\n {showPostSubmitSuggestions && !showModePrompts && (\r\n <QuickSuggestions suggestions={postSubmitSuggestions} />\r\n )}\r\n\r\n <div ref={messagesEndRef} />\r\n </div>\r\n\r\n <div className=\"p-4 border-t dark:border-zinc-800 border-zinc-200 dark:bg-zinc-900 bg-zinc-50\">\r\n <div\r\n className={`flex items-center gap-2 dark:bg-zinc-800 bg-white rounded-full px-4 py-3 border dark:border-zinc-700 border-zinc-300 focus-within:border-[#8B5CF6] transition-colors ${\r\n inputDisabled || showModePrompts ? 'opacity-50 cursor-not-allowed' : ''\r\n }`}\r\n >\r\n <input\r\n type=\"text\"\r\n value={inputValue}\r\n onChange={(e) => setInputValue(e.target.value)}\r\n onKeyPress={(e) => e.key === 'Enter' && handleSend()}\r\n placeholder={\r\n inputDisabled || showModePrompts ? 'Use buttons above...' : 'Ask me anything...'\r\n }\r\n disabled={inputDisabled || showModePrompts}\r\n className=\"flex-1 bg-transparent dark:text-white text-zinc-900 dark:placeholder-zinc-500 placeholder-zinc-400 outline-none text-sm disabled:cursor-not-allowed\"\r\n />\r\n <button\r\n className=\"dark:text-zinc-400 text-zinc-500 dark:hover:text-white hover:text-zinc-900 transition-colors disabled:opacity-50\"\r\n disabled={inputDisabled || showModePrompts}\r\n >\r\n <Mic className=\"w-5 h-5\" />\r\n </button>\r\n <button\r\n onClick={handleSend}\r\n disabled={inputDisabled || showModePrompts}\r\n className=\"bg-[#8B5CF6] hover:bg-[#7C3AED] text-white rounded-full p-2 transition-colors disabled:opacity-50 disabled:cursor-not-allowed\"\r\n >\r\n <Send className=\"w-4 h-4\" />\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\n","// afnBradyApi.ts (library version)\r\n// Utility for integrating with AFN Brady Jr API\r\n\r\n// Use environment variable for API key\r\n// Supports both server (BRADY_API_KEY, BRADY_API_URL) and browser (NEXT_PUBLIC_BRADY_API_KEY, NEXT_PUBLIC_BRADY_API_URL)\r\n// Consumers: Set NEXT_PUBLIC_BRADY_API_KEY and NEXT_PUBLIC_BRADY_API_URL in your app's .env.local for browser use\r\nexport const DEFAULT_BRADY_API_KEY =\r\n typeof process !== 'undefined' && process.env && (\r\n process.env.BRADY_API_KEY || process.env.NEXT_PUBLIC_BRADY_API_KEY\r\n )\r\n ? process.env.BRADY_API_KEY || process.env.NEXT_PUBLIC_BRADY_API_KEY\r\n : 'za2345DDDzXycXKHJvVj80TIsPgooB7iNbwcS9KLzoeaOljlXmJQQJ99BJAC4f1cMXJ3w3AAABACOGQzXz';\r\n\r\nexport const API_URL =\r\n typeof process !== 'undefined' && process.env && (\r\n process.env.BRADY_API_URL || process.env.NEXT_PUBLIC_BRADY_API_URL\r\n )\r\n ? process.env.BRADY_API_URL || process.env.NEXT_PUBLIC_BRADY_API_URL\r\n : 'https://afn-bradyjr-api-dev.azurewebsites.net/';\r\n\r\nexport interface BradyMessage {\r\n role: 'user' | 'assistant' | 'system';\r\n content: string;\r\n}\r\n\r\nexport interface BradyChatRequest {\r\n messages: BradyMessage[];\r\n}\r\n\r\nexport interface BradyChatResponse {\r\n role: string;\r\n type: string;\r\n content: string;\r\n suggestionLink?: { text: string; prompt: string }[];\r\n}\r\n\r\nexport async function sendBradyPrompt(\r\n messages: BradyMessage[],\r\n apiKey: string = DEFAULT_BRADY_API_KEY\r\n): Promise<BradyChatResponse> {\r\n\r\n console.log('[DEFAULT_BRADY_API_KEY]', DEFAULT_BRADY_API_KEY);\r\n console.log('[API_URL]', API_URL);\r\n\r\n const res = await fetch(`${API_URL}/api/chat/prompt`, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'X-API-KEY': apiKey\r\n },\r\n body: JSON.stringify({ messages })\r\n });\r\n if (!res.ok) throw new Error('Brady API error: ' + res.status);\r\n const data = await res.json();\r\n if (process.env.NODE_ENV === 'development') {\r\n // eslint-disable-next-line no-console\r\n console.log('[Brady API Response]', data);\r\n }\r\n return data;\r\n}\r\n\r\n","// bradyHealth.ts (library version)\r\n// Utility to check health of Brady AI API\r\n\r\nimport { API_URL } from './afnBradyApi';\r\n\r\nexport async function checkBradyHealth(): Promise<boolean> {\r\n try {\r\n const res = await fetch(`${API_URL}/api/Health`);\r\n if (!res.ok) return false;\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\n","'use client';\r\n\r\nimport React, { useState } from 'react';\r\nimport { motion } from 'motion/react';\r\n\r\ninterface InfoRequestFormProps {\r\n onSubmit: (data: { firstName: string; lastName: string; email: string; phone?: string }) => void;\r\n onCancel: () => void;\r\n}\r\n\r\nexport function InfoRequestForm({ onSubmit, onCancel }: InfoRequestFormProps) {\r\n const [formData, setFormData] = useState({\r\n firstName: '',\r\n lastName: '',\r\n email: '',\r\n phone: '',\r\n });\r\n const [errors, setErrors] = useState<Record<string, string>>({});\r\n\r\n const handleSubmit = (e: React.FormEvent) => {\r\n e.preventDefault();\r\n const newErrors: Record<string, string> = {};\r\n\r\n if (!formData.firstName.trim()) {\r\n newErrors.firstName = 'First name is required';\r\n }\r\n if (!formData.lastName.trim()) {\r\n newErrors.lastName = 'Last name is required';\r\n }\r\n if (!formData.email.trim()) {\r\n newErrors.email = 'Email is required';\r\n } else if (!/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(formData.email)) {\r\n newErrors.email = 'Please enter a valid email address';\r\n }\r\n\r\n if (Object.keys(newErrors).length > 0) {\r\n setErrors(newErrors);\r\n return;\r\n }\r\n\r\n onSubmit(formData);\r\n };\r\n\r\n return (\r\n <motion.div\r\n initial={{ opacity: 0, y: 10 }}\r\n animate={{ opacity: 1, y: 0 }}\r\n className=\"bg-gradient-to-br from-white to-zinc-50 dark:from-zinc-800 dark:to-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-2xl p-6 max-h-[360px]\"\r\n >\r\n <h3 className=\"text-lg text-zinc-900 dark:text-white mb-4\">Send Me More Information</h3>\r\n\r\n <form onSubmit={handleSubmit} className=\"space-y-3\">\r\n <div>\r\n <input\r\n type=\"text\"\r\n placeholder=\"First Name\"\r\n value={formData.firstName}\r\n onChange={(e) => setFormData({ ...formData, firstName: e.target.value })}\r\n className=\"w-full px-4 py-2.5 bg-white dark:bg-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-lg text-zinc-900 dark:text-white placeholder-zinc-500 focus:border-[#8B5CF6] focus:outline-none transition-colors\"\r\n />\r\n {errors.firstName && <p className=\"text-red-500 text-xs mt-1\">{errors.firstName}</p>}\r\n </div>\r\n\r\n <div>\r\n <input\r\n type=\"text\"\r\n placeholder=\"Last Name\"\r\n value={formData.lastName}\r\n onChange={(e) => setFormData({ ...formData, lastName: e.target.value })}\r\n className=\"w-full px-4 py-2.5 bg-white dark:bg-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-lg text-zinc-900 dark:text-white placeholder-zinc-500 focus:border-[#8B5CF6] focus:outline-none transition-colors\"\r\n />\r\n {errors.lastName && <p className=\"text-red-500 text-xs mt-1\">{errors.lastName}</p>}\r\n </div>\r\n\r\n <div>\r\n <input\r\n type=\"email\"\r\n placeholder=\"Email Address\"\r\n value={formData.email}\r\n onChange={(e) => setFormData({ ...formData, email: e.target.value })}\r\n className=\"w-full px-4 py-2.5 bg-white dark:bg-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-lg text-zinc-900 dark:text-white placeholder-zinc-500 focus:border-[#8B5CF6] focus:outline-none transition-colors\"\r\n />\r\n {errors.email && <p className=\"text-red-500 text-xs mt-1\">{errors.email}</p>}\r\n </div>\r\n\r\n <div>\r\n <input\r\n type=\"tel\"\r\n placeholder=\"Phone (optional)\"\r\n value={formData.phone}\r\n onChange={(e) => setFormData({ ...formData, phone: e.target.value })}\r\n className=\"w-full px-4 py-2.5 bg-white dark:bg-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-lg text-zinc-900 dark:text-white placeholder-zinc-500 focus:border-[#8B5CF6] focus:outline-none transition-colors\"\r\n />\r\n </div>\r\n\r\n <div className=\"flex gap-2 pt-2\">\r\n <button\r\n type=\"submit\"\r\n className=\"flex-1 bg-[#8B5CF6] hover:bg-[#7C3AED] text-white py-2.5 rounded-lg transition-colors\"\r\n >\r\n Send Information\r\n </button>\r\n <button\r\n type=\"button\"\r\n onClick={onCancel}\r\n className=\"px-4 text-zinc-600 dark:text-zinc-400 hover:text-zinc-900 dark:hover:text-white transition-colors\"\r\n >\r\n Cancel\r\n </button>\r\n </div>\r\n </form>\r\n </motion.div>\r\n );\r\n}\r\n\r\n","'use client';\r\n\r\nimport React, { useState } from 'react';\r\nimport { motion } from 'motion/react';\r\nimport { Calendar, Clock } from 'lucide-react';\r\n\r\ninterface LeadershipCallFormProps {\r\n onSubmit: (data: {\r\n firstName: string;\r\n lastName: string;\r\n email: string;\r\n phone: string;\r\n preferredDate?: string;\r\n preferredTime?: string;\r\n }) => void;\r\n onCancel: () => void;\r\n}\r\n\r\nexport function LeadershipCallForm({ onSubmit, onCancel }: LeadershipCallFormProps) {\r\n const [formData, setFormData] = useState({\r\n firstName: '',\r\n lastName: '',\r\n email: '',\r\n phone: '',\r\n preferredDate: '',\r\n preferredTime: '',\r\n });\r\n const [errors, setErrors] = useState<Record<string, string>>({});\r\n\r\n const handleSubmit = (e: React.FormEvent) => {\r\n e.preventDefault();\r\n const newErrors: Record<string, string> = {};\r\n\r\n if (!formData.firstName.trim()) {\r\n newErrors.firstName = 'First name is required';\r\n }\r\n if (!formData.lastName.trim()) {\r\n newErrors.lastName = 'Last name is required';\r\n }\r\n if (!formData.email.trim()) {\r\n newErrors.email = 'Email is required';\r\n } else if (!/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(formData.email)) {\r\n newErrors.email = 'Please enter a valid email address';\r\n }\r\n if (!formData.phone.trim()) {\r\n newErrors.phone = 'Phone number is required';\r\n }\r\n\r\n if (Object.keys(newErrors).length > 0) {\r\n setErrors(newErrors);\r\n return;\r\n }\r\n\r\n onSubmit(formData);\r\n };\r\n\r\n const timeSlots = ['Morning (8am - 12pm)', 'Afternoon (12pm - 5pm)', 'Evening (5pm - 8pm)'];\r\n\r\n return (\r\n <motion.div\r\n initial={{ opacity: 0, y: 10 }}\r\n animate={{ opacity: 1, y: 0 }}\r\n className=\"bg-gradient-to-br from-white to-zinc-50 dark:from-zinc-800 dark:to-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-2xl p-6\"\r\n >\r\n <h3 className=\"text-lg text-zinc-900 dark:text-white mb-4\">Talk to AFN Leadership</h3>\r\n\r\n <form onSubmit={handleSubmit} className=\"space-y-3\">\r\n <div>\r\n <input\r\n type=\"text\"\r\n placeholder=\"First Name\"\r\n value={formData.firstName}\r\n onChange={(e) => setFormData({ ...formData, firstName: e.target.value })}\r\n className=\"w-full px-4 py-2.5 bg-white dark:bg-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-lg text-zinc-900 dark:text-white placeholder-zinc-500 focus:border-[#8B5CF6] focus:outline-none transition-colors\"\r\n />\r\n {errors.firstName && <p className=\"text-red-500 text-xs mt-1\">{errors.firstName}</p>}\r\n </div>\r\n\r\n <div>\r\n <input\r\n type=\"text\"\r\n placeholder=\"Last Name\"\r\n value={formData.lastName}\r\n onChange={(e) => setFormData({ ...formData, lastName: e.target.value })}\r\n className=\"w-full px-4 py-2.5 bg-white dark:bg-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-lg text-zinc-900 dark:text-white placeholder-zinc-500 focus:border-[#8B5CF6] focus:outline-none transition-colors\"\r\n />\r\n {errors.lastName && <p className=\"text-red-500 text-xs mt-1\">{errors.lastName}</p>}\r\n </div>\r\n\r\n <div>\r\n <input\r\n type=\"email\"\r\n placeholder=\"Email Address\"\r\n value={formData.email}\r\n onChange={(e) => setFormData({ ...formData, email: e.target.value })}\r\n className=\"w-full px-4 py-2.5 bg-white dark:bg-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-lg text-zinc-900 dark:text-white placeholder-zinc-500 focus:border-[#8B5CF6] focus:outline-none transition-colors\"\r\n />\r\n {errors.email && <p className=\"text-red-500 text-xs mt-1\">{errors.email}</p>}\r\n </div>\r\n\r\n <div>\r\n <input\r\n type=\"tel\"\r\n placeholder=\"Phone Number\"\r\n value={formData.phone}\r\n onChange={(e) => setFormData({ ...formData, phone: e.target.value })}\r\n className=\"w-full px-4 py-2.5 bg-white dark:bg-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-lg text-zinc-900 dark:text-white placeholder-zinc-500 focus:border-[#8B5CF6] focus:outline-none transition-colors\"\r\n />\r\n {errors.phone && <p className=\"text-red-500 text-xs mt-1\">{errors.phone}</p>}\r\n </div>\r\n\r\n <div className=\"pt-2 border-t border-zinc-200 dark:border-zinc-700\">\r\n <p className=\"text-sm text-zinc-600 dark:text-zinc-400 mb-2\">Preferred Call Time (optional)</p>\r\n <div className=\"grid grid-cols-2 gap-2\">\r\n <div className=\"relative\">\r\n <Calendar className=\"pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-zinc-500\" />\r\n <input\r\n type=\"date\"\r\n value={formData.preferredDate}\r\n onChange={(e) => setFormData({ ...formData, preferredDate: e.target.value })}\r\n className=\"w-full pl-12 pr-4 py-2.5 bg-white dark:bg-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-lg text-zinc-900 dark:text-white text-sm focus:border-[#8B5CF6] focus:outline-none transition-colors\"\r\n />\r\n </div>\r\n <div className=\"relative\">\r\n <Clock className=\"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-zinc-500\" />\r\n <select\r\n value={formData.preferredTime}\r\n onChange={(e) => setFormData({ ...formData, preferredTime: e.target.value })}\r\n className=\"w-full pl-10 pr-4 py-2.5 bg-white dark:bg-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-lg text-zinc-900 dark:text-white text-sm focus:border-[#8B5CF6] focus:outline-none transition-colors appearance-none\"\r\n >\r\n <option value=\"\">Select time</option>\r\n {timeSlots.map((slot) => (\r\n <option key={slot} value={slot}>\r\n {slot}\r\n </option>\r\n ))}\r\n </select>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div className=\"flex gap-2 pt-2\">\r\n <button\r\n type=\"submit\"\r\n className=\"flex-1 bg-[#8B5CF6] hover:bg-[#7C3AED] text-white py-2.5 rounded-lg transition-colors\"\r\n >\r\n Request Call\r\n </button>\r\n <button\r\n type=\"button\"\r\n onClick={onCancel}\r\n className=\"px-4 text-zinc-600 dark:text-zinc-400 hover:text-zinc-900 dark:hover:text-white transition-colors\"\r\n >\r\n Cancel\r\n </button>\r\n </div>\r\n </form>\r\n </motion.div>\r\n );\r\n}\r\n\r\n","'use client';\r\n\r\nimport React, { useState } from 'react';\r\nimport { motion } from 'motion/react';\r\n\r\ninterface PersonalizedOverviewFormProps {\r\n onSubmit: (data: {\r\n firstName: string;\r\n lastName: string;\r\n email: string;\r\n phone?: string;\r\n nmlsId?: string;\r\n }) => void;\r\n onCancel: () => void;\r\n}\r\n\r\nexport function PersonalizedOverviewForm({ onSubmit, onCancel }: PersonalizedOverviewFormProps) {\r\n const [formData, setFormData] = useState({\r\n firstName: '',\r\n lastName: '',\r\n email: '',\r\n phone: '',\r\n nmlsId: '',\r\n });\r\n const [errors, setErrors] = useState<Record<string, string>>({});\r\n\r\n const handleSubmit = (e: React.FormEvent) => {\r\n e.preventDefault();\r\n const newErrors: Record<string, string> = {};\r\n\r\n if (!formData.firstName.trim()) {\r\n newErrors.firstName = 'First name is required';\r\n }\r\n if (!formData.lastName.trim()) {\r\n newErrors.lastName = 'Last name is required';\r\n }\r\n if (!formData.email.trim()) {\r\n newErrors.email = 'Email is required';\r\n } else if (!/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(formData.email)) {\r\n newErrors.email = 'Please enter a valid email address';\r\n }\r\n\r\n if (Object.keys(newErrors).length > 0) {\r\n setErrors(newErrors);\r\n return;\r\n }\r\n\r\n onSubmit(formData);\r\n };\r\n\r\n return (\r\n <motion.div\r\n initial={{ opacity: 0, y: 10 }}\r\n animate={{ opacity: 1, y: 0 }}\r\n className=\"bg-gradient-to-br from-white to-zinc-50 dark:from-zinc-800 dark:to-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-2xl p-6\"\r\n >\r\n <h3 className=\"text-lg text-zinc-900 dark:text-white mb-4\">Request Personalized Overview</h3>\r\n\r\n <form onSubmit={handleSubmit} className=\"space-y-3\">\r\n <div>\r\n <input\r\n type=\"text\"\r\n placeholder=\"First Name\"\r\n value={formData.firstName}\r\n onChange={(e) => setFormData({ ...formData, firstName: e.target.value })}\r\n className=\"w-full px-4 py-2.5 bg-white dark:bg-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-lg text-zinc-900 dark:text-white placeholder-zinc-500 focus:border-[#8B5CF6] focus:outline-none transition-colors\"\r\n />\r\n {errors.firstName && <p className=\"text-red-500 text-xs mt-1\">{errors.firstName}</p>}\r\n </div>\r\n\r\n <div>\r\n <input\r\n type=\"text\"\r\n placeholder=\"Last Name\"\r\n value={formData.lastName}\r\n onChange={(e) => setFormData({ ...formData, lastName: e.target.value })}\r\n className=\"w-full px-4 py-2.5 bg-white dark:bg-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-lg text-zinc-900 dark:text-white placeholder-zinc-500 focus:border-[#8B5CF6] focus:outline-none transition-colors\"\r\n />\r\n {errors.lastName && <p className=\"text-red-500 text-xs mt-1\">{errors.lastName}</p>}\r\n </div>\r\n\r\n <div>\r\n <input\r\n type=\"email\"\r\n placeholder=\"Email Address\"\r\n value={formData.email}\r\n onChange={(e) => setFormData({ ...formData, email: e.target.value })}\r\n className=\"w-full px-4 py-2.5 bg-white dark:bg-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-lg text-zinc-900 dark:text-white placeholder-zinc-500 focus:border-[#8B5CF6] focus:outline-none transition-colors\"\r\n />\r\n {errors.email && <p className=\"text-red-500 text-xs mt-1\">{errors.email}</p>}\r\n </div>\r\n\r\n <div>\r\n <input\r\n type=\"tel\"\r\n placeholder=\"Phone (optional)\"\r\n value={formData.phone}\r\n onChange={(e) => setFormData({ ...formData, phone: e.target.value })}\r\n className=\"w-full px-4 py-2.5 bg-white dark:bg-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-lg text-zinc-900 dark:text-white placeholder-zinc-500 focus:border-[#8B5CF6] focus:outline-none transition-colors\"\r\n />\r\n </div>\r\n\r\n <div>\r\n <input\r\n type=\"text\"\r\n placeholder=\"NMLS ID (optional)\"\r\n value={formData.nmlsId}\r\n onChange={(e) => setFormData({ ...formData, nmlsId: e.target.value })}\r\n className=\"w-full px-4 py-2.5 bg-white dark:bg-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-lg text-zinc-900 dark:text-white placeholder-zinc-500 focus:border-[#8B5CF6] focus:outline-none transition-colors\"\r\n />\r\n </div>\r\n\r\n <div className=\"flex gap-2 pt-2\">\r\n <button\r\n type=\"submit\"\r\n className=\"flex-1 bg-[#8B5CF6] hover:bg-[#7C3AED] text-white py-2.5 rounded-lg transition-colors\"\r\n >\r\n Request Overview\r\n </button>\r\n <button\r\n type=\"button\"\r\n onClick={onCancel}\r\n className=\"px-4 text-zinc-600 dark:text-zinc-400 hover:text-zinc-900 dark:hover:text-white transition-colors\"\r\n >\r\n Cancel\r\n </button>\r\n </div>\r\n </form>\r\n </motion.div>\r\n );\r\n}\r\n\r\n","'use client';\r\n\r\nimport { motion } from 'motion/react';\r\n\r\ninterface QuickSuggestion {\r\n text: string;\r\n action: () => void;\r\n}\r\n\r\ninterface QuickSuggestionsProps {\r\n suggestions: QuickSuggestion[];\r\n}\r\n\r\nexport function QuickSuggestions({ suggestions }: QuickSuggestionsProps) {\r\n return (\r\n <motion.div\r\n initial={{ opacity: 0, y: 10 }}\r\n animate={{ opacity: 1, y: 0 }}\r\n className=\"flex flex-wrap gap-2\"\r\n >\r\n {suggestions.map((suggestion, idx) => (\r\n <button\r\n key={idx}\r\n onClick={suggestion.action}\r\n className=\"px-3 py-1.5 bg-zinc-100 dark:bg-zinc-800 hover:bg-zinc-200 dark:hover:bg-zinc-700 text-zinc-700 dark:text-zinc-300 text-sm rounded-full border border-zinc-300 dark:border-zinc-700 transition-colors\"\r\n >\r\n {suggestion.text}\r\n </button>\r\n ))}\r\n </motion.div>\r\n );\r\n}\r\n\r\n","'use client';\r\n\r\nimport { motion } from 'motion/react';\r\n\r\ninterface ModePromptTreeProps {\r\n mode: 'earnings' | 'profit';\r\n step: string;\r\n hasPersonalizedData: boolean;\r\n onResponse: (response: string, data?: any) => void;\r\n}\r\n\r\nexport function ModePromptTree({ mode, step, hasPersonalizedData, onResponse }: ModePromptTreeProps) {\r\n if (mode === 'earnings') {\r\n if (step === 'volume') {\r\n if (hasPersonalizedData) {\r\n return (\r\n <motion.div initial={{ opacity: 0, y: 10 }} animate={{ opacity: 1, y: 0 }} className=\"space-y-3\">\r\n <div className=\"grid grid-cols-1 gap-2\">\r\n <button\r\n onClick={() => onResponse('yes', { volumeMultiplier: 1.0 })}\r\n className=\"px-4 py-3 bg-[#8B5CF6] hover:bg-[#7C3AED] text-white rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Yes, that's about right\r\n </button>\r\n <button\r\n onClick={() => onResponse('higher', { volumeMultiplier: 1.1 })}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n It's a bit higher\r\n </button>\r\n <button\r\n onClick={() => onResponse('lower', { volumeMultiplier: 0.9 })}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n It's a bit lower\r\n </button>\r\n </div>\r\n </motion.div>\r\n );\r\n }\r\n\r\n return (\r\n <motion.div initial={{ opacity: 0, y: 10 }} animate={{ opacity: 1, y: 0 }} className=\"space-y-3\">\r\n <div className=\"grid grid-cols-1 gap-2\">\r\n <button\r\n onClick={() => onResponse('Under $500k', { volume: 400000 })}\r\n className=\"px-4 py-3 bg-[#8B5CF6] hover:bg-[#7C3AED] text-white rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Under $500k\r\n </button>\r\n <button\r\n onClick={() => onResponse('$500k – $1M', { volume: 750000 })}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n $500k – $1M\r\n </button>\r\n <button\r\n onClick={() => onResponse('$1M – $2M', { volume: 1500000 })}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n $1M – $2M\r\n </button>\r\n <button\r\n onClick={() => onResponse('$2M+', { volume: 2500000 })}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n $2M+\r\n </button>\r\n </div>\r\n </motion.div>\r\n );\r\n }\r\n\r\n if (step === 'comp') {\r\n return (\r\n <motion.div initial={{ opacity: 0, y: 10 }} animate={{ opacity: 1, y: 0 }} className=\"space-y-3\">\r\n <div className=\"grid grid-cols-1 gap-2\">\r\n <button\r\n onClick={() => onResponse('Under 100 bps', { comp: 0.95 })}\r\n className=\"px-4 py-3 bg-[#8B5CF6] hover:bg-[#7C3AED] text-white rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Under 100 bps\r\n </button>\r\n <button\r\n onClick={() => onResponse('Around 125 bps', { comp: 1.25 })}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Around 125 bps\r\n </button>\r\n <button\r\n onClick={() => onResponse('150+ bps', { comp: 1.5 })}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n 150+ bps\r\n </button>\r\n <button\r\n onClick={() => onResponse(\"I'm not sure\", { comp: 1.15 })}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n I'm not sure\r\n </button>\r\n </div>\r\n </motion.div>\r\n );\r\n }\r\n\r\n if (step === 'complete') {\r\n return (\r\n <motion.div initial={{ opacity: 0, y: 10 }} animate={{ opacity: 1, y: 0 }} className=\"space-y-3\">\r\n <div className=\"grid grid-cols-1 gap-2\">\r\n <button\r\n onClick={() => onResponse('Talk through this with AFN')}\r\n className=\"px-4 py-3 bg-[#8B5CF6] hover:bg-[#7C3AED] text-white rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Talk through this with AFN\r\n </button>\r\n <button\r\n onClick={() => onResponse('Adjust the numbers')}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Adjust the numbers\r\n </button>\r\n <button\r\n onClick={() => onResponse('Keep exploring')}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Keep exploring\r\n </button>\r\n </div>\r\n </motion.div>\r\n );\r\n }\r\n }\r\n\r\n if (mode === 'profit') {\r\n if (step === 'volume') {\r\n if (hasPersonalizedData) {\r\n return (\r\n <motion.div initial={{ opacity: 0, y: 10 }} animate={{ opacity: 1, y: 0 }} className=\"space-y-3\">\r\n <div className=\"grid grid-cols-1 gap-2\">\r\n <button\r\n onClick={() => onResponse('Yes', { volumeMultiplier: 1.0 })}\r\n className=\"px-4 py-3 bg-[#4399D1] hover:bg-[#2B7AB8] text-white rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Yes\r\n </button>\r\n <button\r\n onClick={() => onResponse('Volume is higher', { volumeMultiplier: 1.1 })}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Volume is higher\r\n </button>\r\n <button\r\n onClick={() => onResponse('Volume is lower', { volumeMultiplier: 0.9 })}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Volume is lower\r\n </button>\r\n </div>\r\n </motion.div>\r\n );\r\n }\r\n\r\n return (\r\n <motion.div initial={{ opacity: 0, y: 10 }} animate={{ opacity: 1, y: 0 }} className=\"space-y-3\">\r\n <div className=\"grid grid-cols-1 gap-2\">\r\n <button\r\n onClick={() => onResponse('Under $100M', { volume: 75000000 })}\r\n className=\"px-4 py-3 bg-[#4399D1] hover:bg-[#2B7AB8] text-white rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Under $100M\r\n </button>\r\n <button\r\n onClick={() => onResponse('$100M – $250M', { volume: 175000000 })}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n $100M – $250M\r\n </button>\r\n <button\r\n onClick={() => onResponse('$250M – $500M', { volume: 375000000 })}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n $250M – $500M\r\n </button>\r\n <button\r\n onClick={() => onResponse('$500M+', { volume: 650000000 })}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n $500M+\r\n </button>\r\n </div>\r\n </motion.div>\r\n );\r\n }\r\n\r\n if (step === 'economics') {\r\n return (\r\n <motion.div initial={{ opacity: 0, y: 10 }} animate={{ opacity: 1, y: 0 }} className=\"space-y-3\">\r\n <div className=\"grid grid-cols-1 gap-2\">\r\n <button\r\n onClick={() => onResponse('Sounds right', { margin: 3.0, grossProfit: 1.5, opEx: 0.75 })}\r\n className=\"px-4 py-3 bg-[#4399D1] hover:bg-[#2B7AB8] text-white rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Sounds right\r\n </button>\r\n <button\r\n onClick={() =>\r\n onResponse('Margin is higher', {\r\n margin: 3.5,\r\n grossProfit: 1.75,\r\n opEx: 0.75,\r\n })\r\n }\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Margin is higher\r\n </button>\r\n <button\r\n onClick={() =>\r\n onResponse('Expenses are higher', {\r\n margin: 3.0,\r\n grossProfit: 1.5,\r\n opEx: 0.95,\r\n })\r\n }\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Expenses are higher\r\n </button>\r\n <button\r\n onClick={() =>\r\n onResponse('Let me adjust', {\r\n margin: 3.0,\r\n grossProfit: 1.5,\r\n opEx: 0.75,\r\n })\r\n }\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Let me adjust\r\n </button>\r\n </div>\r\n </motion.div>\r\n );\r\n }\r\n\r\n if (step === 'complete') {\r\n return (\r\n <motion.div initial={{ opacity: 0, y: 10 }} animate={{ opacity: 1, y: 0 }} className=\"space-y-3\">\r\n <div className=\"grid grid-cols-1 gap-2\">\r\n <button\r\n onClick={() => onResponse('Sanity-check with AFN')}\r\n className=\"px-4 py-3 bg-[#4399D1] hover:bg-[#2B7AB8] text-white rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Sanity-check with AFN\r\n </button>\r\n <button\r\n onClick={() => onResponse('Adjust assumptions')}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Adjust assumptions\r\n </button>\r\n <button\r\n onClick={() => onResponse('Schedule leadership call')}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Schedule leadership call\r\n </button>\r\n </div>\r\n </motion.div>\r\n );\r\n }\r\n }\r\n\r\n return null;\r\n}\r\n\r\n","import React, { useState } from 'react';\r\n\r\nconst ERROR_IMG_SRC =\r\n 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iODgiIGhlaWdodD0iODgiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBvcGFjaXR5PSIuMyIgZmlsbD0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIzLjciPjxyZWN0IHg9IjE2IiB5PSIxNiIgd2lkdGg9IjU2IiBoZWlnaHQ9IjU2IiByeD0iNiIvPjxwYXRoIGQ9Im0xNiA1OCAxNi0xOCAzMiAzMiIvPjxjaXJjbGUgY3g9IjUzIiBjeT0iMzUiIHI9IjciLz48L3N2Zz4KCg==';\r\n\r\nexport function ImageWithFallback(props: React.ImgHTMLAttributes<HTMLImageElement>) {\r\n const [didError, setDidError] = useState(false);\r\n\r\n const handleError = () => {\r\n setDidError(true);\r\n };\r\n\r\n const { src, alt, style, className, ...rest } = props;\r\n\r\n return didError ? (\r\n <div\r\n className={`inline-block bg-gray-100 text-center align-middle ${className ?? ''}`}\r\n style={style}\r\n >\r\n <div className=\"flex items-center justify-center w-full h-full\">\r\n <img src={ERROR_IMG_SRC} alt=\"Error loading image\" {...rest} data-original-url={src} />\r\n </div>\r\n </div>\r\n ) : (\r\n <img src={src} alt={alt} className={className} style={style} {...rest} onError={handleError} />\r\n );\r\n}\r\n\r\n"],"mappings":"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","names":["useState","motion","useState","jsx","useState","motion","jsx","jsxs","useState","motion","jsx","jsxs","motion","jsx","motion","jsx","jsxs","useState","jsx","jsx","jsxs","useState","motion"]}
1
+ {"version":3,"sources":["../src/lib/BradyChatContext.tsx","../src/lib/EnhancedBradyChat.tsx","../src/lib/api/afnBradyApi.ts","../src/lib/api/bradyHealth.ts","../src/lib/InfoRequestForm.tsx","../src/lib/LeadershipCallForm.tsx","../src/lib/PersonalizedOverviewForm.tsx","../src/lib/QuickSuggestions.tsx","../src/lib/ModePromptTree.tsx","../src/lib/ImageWithFallback.tsx"],"sourcesContent":["'use client';\r\n\r\nimport React, { createContext, useContext, useState, ReactNode } from 'react';\r\n\r\nexport type ChatWorkflowType =\r\n | 'free'\r\n | 'info-request'\r\n | 'leadership-call'\r\n | 'personalized-overview-request'\r\n | 'earnings-mode'\r\n | 'profit-mode';\r\nexport type ModeType = 'none' | 'earnings' | 'profit';\r\nexport type ModeStep = 'initial' | 'volume' | 'comp' | 'economics' | 'calculator' | 'complete';\r\n\r\nexport interface ChatMessage {\r\n type: 'user' | 'brady' | 'form';\r\n text?: string;\r\n component?: ReactNode;\r\n}\r\n\r\ninterface ModeData {\r\n volume?: number;\r\n comp?: number;\r\n margin?: number;\r\n grossProfit?: number;\r\n opEx?: number;\r\n volumeMultiplier?: number;\r\n}\r\n\r\ninterface BradyChatContextType {\r\n workflowType: ChatWorkflowType;\r\n messages: ChatMessage[];\r\n startWorkflow: (workflow: ChatWorkflowType) => void;\r\n addMessage: (message: ChatMessage) => void;\r\n setWorkflow: (workflow: ChatWorkflowType) => void;\r\n resetChat: () => void;\r\n // Mode system\r\n activeMode: ModeType;\r\n modeStep: ModeStep;\r\n modeData: ModeData;\r\n activateMode: (mode: ModeType) => void;\r\n setModeStep: (step: ModeStep) => void;\r\n updateModeData: (data: Partial<ModeData>) => void;\r\n resetMode: () => void;\r\n // Calculator control\r\n calculatorOpen: boolean;\r\n setCalculatorOpen: (open: boolean) => void;\r\n isHidden: boolean;\r\n setIsHidden: React.Dispatch<React.SetStateAction<boolean>>;\r\n // Modal-aware Brady AI\r\n hideBradyForModal: () => void;\r\n restoreBradyAfterModal: () => void;\r\n}\r\n\r\nconst BradyChatContext = createContext<BradyChatContextType | undefined>(undefined);\r\n\r\nconst initialMessages: ChatMessage[] = [\r\n {\r\n type: 'user',\r\n text: \"introduce\",\r\n },\r\n];\r\n\r\nexport function BradyChatProvider({ children }: { children: ReactNode }) {\r\n const [workflowType, setWorkflowType] = useState<ChatWorkflowType>('free');\r\n const [messages, setMessages] = useState<ChatMessage[]>(initialMessages);\r\n // Mode system state\r\n const [activeMode, setActiveMode] = useState<ModeType>('none');\r\n const [modeStep, setModeStep] = useState<ModeStep>('initial');\r\n const [modeData, setModeData] = useState<ModeData>({});\r\n const [calculatorOpen, setCalculatorOpen] = useState(false);\r\n // Global hide/show state for Brady chat (default hidden)\r\n const [isHidden, setIsHidden] = useState(true);\r\n // Track previous visibility for modal\r\n const [wasBradyVisibleBeforeModal, setWasBradyVisibleBeforeModal] = useState(false);\r\n\r\n // Modal-aware hide/show\r\n const hideBradyForModal = () => {\r\n setWasBradyVisibleBeforeModal(!isHidden);\r\n setIsHidden(true);\r\n };\r\n const restoreBradyAfterModal = () => {\r\n if (wasBradyVisibleBeforeModal) setIsHidden(false);\r\n };\r\n\r\n const startWorkflow = (workflow: ChatWorkflowType) => {\r\n setWorkflowType(workflow);\r\n\r\n // Set appropriate initial message based on workflow\r\n if (workflow === 'info-request') {\r\n setMessages([\r\n {\r\n type: 'brady',\r\n text: \"Happy to send you a personalized overview.\\n\\nIf you share your contact details below, we'll email you more information about AFN and how it could fit your goals.\",\r\n },\r\n ]);\r\n } else if (workflow === 'leadership-call') {\r\n setMessages([\r\n {\r\n type: 'brady',\r\n text: \"Happy to connect you with AFN leadership.\\n\\nShare your details below and we'll have someone reach out shortly.\\nIf you'd like, you can also suggest a good time to talk.\",\r\n },\r\n ]);\r\n } else if (workflow === 'personalized-overview-request') {\r\n setMessages([\r\n {\r\n type: 'brady',\r\n text: \"I'll help you get a personalized dashboard and earnings calculator.\\n\\nShare your details below and we'll create a custom overview showing exactly what your business could look like at AFN.\",\r\n },\r\n ]);\r\n } else {\r\n setMessages(initialMessages);\r\n }\r\n };\r\n\r\n const addMessage = (message: ChatMessage) => {\r\n setMessages((prev) => [...prev, message]);\r\n };\r\n\r\n const setWorkflow = (workflow: ChatWorkflowType) => {\r\n setWorkflowType(workflow);\r\n };\r\n\r\n const resetChat = () => {\r\n setWorkflowType('free');\r\n setMessages(initialMessages);\r\n resetMode();\r\n };\r\n\r\n // Mode system functions\r\n const activateMode = (mode: ModeType) => {\r\n setActiveMode(mode);\r\n setModeStep('initial');\r\n setModeData({});\r\n\r\n // Set initial mode message\r\n if (mode === 'earnings') {\r\n setMessages([\r\n {\r\n type: 'brady',\r\n text: \"Earnings Mode is on.\\n\\nI'll focus on how volume, efficiency, and time savings can impact your income.\",\r\n },\r\n ]);\r\n setModeStep('volume');\r\n } else if (mode === 'profit') {\r\n setMessages([\r\n {\r\n type: 'brady',\r\n text: 'Profit Mode is on.\\n\\nI\\'ll focus on branch economics—volume, margin, expenses, and profitability.',\r\n },\r\n ]);\r\n setModeStep('volume');\r\n }\r\n };\r\n\r\n const updateModeData = (data: Partial<ModeData>) => {\r\n setModeData((prev) => ({ ...prev, ...data }));\r\n };\r\n\r\n const resetMode = () => {\r\n setActiveMode('none');\r\n setModeStep('initial');\r\n setModeData({});\r\n setCalculatorOpen(false);\r\n };\r\n\r\n return (\r\n <BradyChatContext.Provider\r\n value={{\r\n workflowType,\r\n messages,\r\n startWorkflow,\r\n addMessage,\r\n setWorkflow,\r\n resetChat,\r\n activeMode,\r\n modeStep,\r\n modeData,\r\n activateMode,\r\n setModeStep,\r\n updateModeData,\r\n resetMode,\r\n calculatorOpen,\r\n setCalculatorOpen,\r\n isHidden,\r\n setIsHidden,\r\n hideBradyForModal,\r\n restoreBradyAfterModal,\r\n }}\r\n >\r\n {children}\r\n </BradyChatContext.Provider>\r\n );\r\n}\r\n\r\nexport function useBradyChat() {\r\n const context = useContext(BradyChatContext);\r\n if (context === undefined) {\r\n throw new Error('useBradyChat must be used within a BradyChatProvider');\r\n }\r\n return context;\r\n}\r\n\r\n","'use client';\r\n\r\nimport { useState, useRef, useEffect } from 'react';\r\nimport { motion, AnimatePresence } from 'motion/react';\r\nimport { Send, Mic } from 'lucide-react';\r\n\r\nimport { checkBradyHealth } from './api/bradyHealth';\r\nimport { sendBradyPrompt } from './api/afnBradyApi';\r\nimport { useBradyChat } from './BradyChatContext';\r\nimport { InfoRequestForm } from './InfoRequestForm';\r\nimport { LeadershipCallForm } from './LeadershipCallForm';\r\nimport { PersonalizedOverviewForm } from './PersonalizedOverviewForm';\r\nimport { QuickSuggestions } from './QuickSuggestions';\r\nimport { ModePromptTree } from './ModePromptTree';\r\nimport { ImageWithFallback } from './ImageWithFallback';\r\n\r\ntype ModeVariant = 'loan-officer' | 'branch-manager';\r\n\r\nexport interface EnhancedBradyChatProps {\r\n /**\r\n * Controls whether the mode toggle uses Earnings (LO) or Profit (branch manager) language.\r\n * Defaults to 'loan-officer'.\r\n */\r\n modeVariant?: ModeVariant;\r\n /**\r\n * Avatar image URL for Brady.\r\n * Typically you pass something like `/bradyIcon.png` from your app's public assets.\r\n */\r\n avatarSrc: string;\r\n}\r\n\r\nexport function EnhancedBradyChat({ modeVariant = 'loan-officer', avatarSrc }: EnhancedBradyChatProps) {\r\n const [bradyHealthy, setBradyHealthy] = useState(true);\r\n const {\r\n workflowType,\r\n messages,\r\n addMessage,\r\n resetChat,\r\n setWorkflow,\r\n activeMode,\r\n modeStep,\r\n modeData,\r\n setModeStep,\r\n updateModeData,\r\n setCalculatorOpen,\r\n activateMode,\r\n resetMode,\r\n isHidden,\r\n setIsHidden,\r\n } = useBradyChat();\r\n const [inputValue, setInputValue] = useState('');\r\n const [showForm, setShowForm] = useState(false);\r\n const [inputDisabled, setInputDisabled] = useState(false);\r\n const [showModePrompts, setShowModePrompts] = useState(false);\r\n const messagesEndRef = useRef<HTMLDivElement>(null);\r\n const [suggestionLinks, setSuggestionLinks] = useState<{ text: string; prompt: string }[] | null>(null);\r\n\r\n const isBranchManager = modeVariant === 'branch-manager';\r\n const pageMode = isBranchManager ? 'profit' : 'earnings';\r\n const isModeActive = activeMode === pageMode;\r\n const hasPersonalizedData = false;\r\n\r\n const handleFocusToggle = () => {\r\n if (isModeActive) {\r\n resetMode();\r\n } else {\r\n activateMode(pageMode);\r\n setTimeout(() => {\r\n addMessage({\r\n type: 'brady',\r\n text: `${\r\n isBranchManager ? 'Profit' : 'Earnings'\r\n } Mode is on.\\n\\nI'll focus on ways to increase ${\r\n isBranchManager ? 'profit' : 'income'\r\n } using ${\r\n isBranchManager\r\n ? 'branch economics, recruiting leverage, and operational efficiency'\r\n : 'volume, efficiency, and time savings'\r\n }.`,\r\n });\r\n }, 300);\r\n }\r\n };\r\n\r\n useEffect(() => {\r\n let mounted = true;\r\n const checkHealth = async () => {\r\n const healthy = await checkBradyHealth();\r\n if (mounted) setBradyHealthy(healthy);\r\n };\r\n checkHealth();\r\n const interval = setInterval(checkHealth, 60000);\r\n return () => {\r\n mounted = false;\r\n clearInterval(interval);\r\n };\r\n }, []);\r\n\r\n useEffect(() => {\r\n if (\r\n workflowType === 'info-request' ||\r\n workflowType === 'leadership-call' ||\r\n workflowType === 'personalized-overview-request'\r\n ) {\r\n setShowForm(true);\r\n setInputDisabled(true);\r\n setShowModePrompts(false);\r\n } else {\r\n setShowForm(false);\r\n setInputDisabled(false);\r\n }\r\n }, [workflowType]);\r\n\r\n useEffect(() => {\r\n if (activeMode !== 'none' && modeStep === 'volume') {\r\n setShowModePrompts(true);\r\n\r\n if (activeMode === 'earnings') {\r\n if (hasPersonalizedData) {\r\n setTimeout(() => {\r\n addMessage({\r\n type: 'brady',\r\n text: 'I have an estimate of your recent production.\\nDoes this feel close?',\r\n });\r\n }, 500);\r\n } else {\r\n setTimeout(() => {\r\n addMessage({\r\n type: 'brady',\r\n text: 'To keep this realistic, about how much volume do you fund in an average month?',\r\n });\r\n }, 500);\r\n }\r\n } else if (activeMode === 'profit') {\r\n if (hasPersonalizedData) {\r\n setTimeout(() => {\r\n addMessage({\r\n type: 'brady',\r\n text: 'I have a baseline view of your branch.\\nDoes this feel directionally right?',\r\n });\r\n }, 500);\r\n } else {\r\n setTimeout(() => {\r\n addMessage({\r\n type: 'brady',\r\n text: 'To start, about how much volume does your branch fund annually?',\r\n });\r\n }, 500);\r\n }\r\n }\r\n }\r\n }, [activeMode, modeStep, addMessage]);\r\n\r\n useEffect(() => {\r\n scrollToBottom();\r\n }, [messages, showForm, showModePrompts]);\r\n\r\n const scrollToBottom = () => {\r\n messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });\r\n };\r\n\r\n const handleModeResponse = (response: string, data?: any) => {\r\n addMessage({ type: 'user', text: response });\r\n setShowModePrompts(false);\r\n\r\n if (data) {\r\n updateModeData(data);\r\n }\r\n\r\n if (activeMode === 'earnings') {\r\n if (modeStep === 'volume') {\r\n setTimeout(() => {\r\n addMessage({\r\n type: 'brady',\r\n text: 'And roughly how do you get paid today?',\r\n });\r\n setModeStep('comp');\r\n setShowModePrompts(true);\r\n }, 800);\r\n } else if (modeStep === 'comp') {\r\n setTimeout(() => {\r\n addMessage({\r\n type: 'brady',\r\n text: \"Got it. I'll pull this together so you can see it clearly.\",\r\n });\r\n setModeStep('calculator');\r\n setTimeout(() => {\r\n setCalculatorOpen(true);\r\n setModeStep('complete');\r\n setTimeout(() => {\r\n addMessage({\r\n type: 'brady',\r\n text: 'Want to sanity-check these assumptions together?',\r\n });\r\n setShowModePrompts(true);\r\n }, 1000);\r\n }, 800);\r\n }, 800);\r\n } else if (modeStep === 'complete') {\r\n if (response.includes('Talk through')) {\r\n setShowModePrompts(false);\r\n setTimeout(() => {\r\n startWorkflow('leadership-call');\r\n }, 500);\r\n } else if (response.includes('Adjust')) {\r\n setShowModePrompts(false);\r\n setTimeout(() => {\r\n setCalculatorOpen(true);\r\n }, 500);\r\n } else {\r\n setShowModePrompts(false);\r\n setTimeout(() => {\r\n addMessage({\r\n type: 'brady',\r\n text: \"I'm here whenever you need me. What else would you like to explore?\",\r\n });\r\n }, 800);\r\n }\r\n }\r\n } else if (activeMode === 'profit') {\r\n if (modeStep === 'volume') {\r\n setTimeout(() => {\r\n addMessage({\r\n type: 'brady',\r\n text:\r\n \"For modeling, I'll assume:\\n• ~300 bps branch margin\\n• ~150 bps gross profit\\n\" +\r\n '• ~75 bps operating expenses\\n\\nWe can adjust all of this.',\r\n });\r\n setModeStep('economics');\r\n setShowModePrompts(true);\r\n }, 800);\r\n } else if (modeStep === 'economics') {\r\n setTimeout(() => {\r\n addMessage({\r\n type: 'brady',\r\n text: \"Here's a clean P&L view based on what we discussed.\",\r\n });\r\n setModeStep('calculator');\r\n setTimeout(() => {\r\n setCalculatorOpen(true);\r\n setModeStep('complete');\r\n setTimeout(() => {\r\n addMessage({\r\n type: 'brady',\r\n text: \"Want help building a realistic pro forma based on AFN's structure?\",\r\n });\r\n setShowModePrompts(true);\r\n }, 1000);\r\n }, 800);\r\n }, 800);\r\n } else if (modeStep === 'complete') {\r\n if (response.includes('Sanity-check') || response.includes('leadership')) {\r\n setShowModePrompts(false);\r\n setTimeout(() => {\r\n startWorkflow('leadership-call');\r\n }, 500);\r\n } else if (response.includes('Adjust')) {\r\n setShowModePrompts(false);\r\n setTimeout(() => {\r\n setCalculatorOpen(true);\r\n }, 500);\r\n }\r\n }\r\n }\r\n };\r\n\r\n const handleSend = async () => {\r\n if (inputValue.trim() && !inputDisabled) {\r\n const userText = inputValue;\r\n addMessage({ type: 'user', text: userText });\r\n setInputValue('');\r\n \r\n try {\r\n const apiResponse = await sendBradyPrompt([{ role: 'user', content: userText }]);\r\n let mappedType: 'user' | 'brady' | 'form' = 'brady';\r\n if (apiResponse.role === 'user') mappedType = 'user';\r\n addMessage({ type: mappedType, text: apiResponse.content });\r\n } catch {\r\n addMessage({ type: 'brady', text: 'Sorry, Brady AI is currently unavailable.' });\r\n }\r\n }\r\n };\r\n\r\n const handleQuickSuggestion = async (text: string) => {\r\n addMessage({ type: 'user', text });\r\n try {\r\n const apiResponse = await sendBradyPrompt([{ role: 'user', content: text }]);\r\n\r\n if (Array.isArray(apiResponse.suggestionLink)) {\r\n setSuggestionLinks(apiResponse.suggestionLink);\r\n }\r\n\r\n let mappedType: 'user' | 'brady' | 'form' = 'brady';\r\n if (apiResponse.role === 'user') mappedType = 'user';\r\n addMessage({ type: mappedType, text: apiResponse.content });\r\n } catch {\r\n addMessage({ type: 'brady', text: 'Sorry, Brady AI is currently unavailable.' });\r\n }\r\n };\r\n\r\n const handleInfoFormSubmit = (data: any) => {\r\n addMessage({\r\n type: 'brady',\r\n text:\r\n \"Got it — thanks.\\n\\nWe'll email you a personalized overview shortly.\\nIf you have questions in the meantime, I'm here to help.\",\r\n });\r\n setShowForm(false);\r\n setInputDisabled(false);\r\n setWorkflow('free');\r\n };\r\n\r\n const handleLeadershipFormSubmit = (data: any) => {\r\n addMessage({\r\n type: 'brady',\r\n text:\r\n \"Thanks — you're all set.\\n\\nSomeone from AFN leadership will reach out shortly to connect.\\nIn the meantime, feel free to ask me anything.\",\r\n });\r\n setShowForm(false);\r\n setInputDisabled(false);\r\n setWorkflow('free');\r\n };\r\n\r\n const handlePersonalizedOverviewFormSubmit = (data: any) => {\r\n addMessage({\r\n type: 'brady',\r\n text:\r\n \"Perfect — thanks!\\n\\nWe'll create a personalized dashboard and earnings calculator based on your information and send it to you shortly.\\n\\nYou'll be able to see exactly what your business could look like at AFN with specific projections tailored to your situation.\",\r\n });\r\n setShowForm(false);\r\n setInputDisabled(false);\r\n setWorkflow('free');\r\n };\r\n\r\n const handleFormCancel = () => {\r\n setShowForm(false);\r\n setInputDisabled(false);\r\n resetChat();\r\n };\r\n\r\n const buildSuggestions = () => {\r\n if (suggestionLinks && suggestionLinks.length > 0) {\r\n return suggestionLinks.map((s) => ({\r\n text: s.text,\r\n action: () => handleQuickSuggestion(s.prompt),\r\n }));\r\n }\r\n return [];\r\n };\r\n\r\n const initialSuggestions = buildSuggestions();\r\n const postSubmitSuggestions = buildSuggestions();\r\n\r\n const showPostSubmitSuggestions = messages.length > 2 && !showForm && workflowType === 'free' && activeMode === 'none';\r\n\r\n const startWorkflow = (workflow: any) => {\r\n setWorkflow(workflow);\r\n if (workflow === 'info-request') {\r\n setShowForm(true);\r\n setInputDisabled(true);\r\n } else if (workflow === 'leadership-call') {\r\n setShowForm(true);\r\n setInputDisabled(true);\r\n }\r\n };\r\n\r\n const modeBadge =\r\n activeMode !== 'none' ? (\r\n <div\r\n className={`px-3 py-1 rounded-full text-xs font-medium ${\r\n activeMode === 'earnings'\r\n ? 'bg-[#8B5CF6]/20 text-[#8B5CF6] border border-[#8B5CF6]/30'\r\n : 'bg-[#4399D1]/20 text-[#4399D1] border border-[#4399D1]/30'\r\n }`}\r\n >\r\n {activeMode === 'earnings' ? 'Earnings Mode' : 'Profit Mode'}\r\n </div>\r\n ) : null;\r\n\r\n if (isHidden) return null;\r\n \r\n\r\n return (\r\n <div className=\"fixed top-0 right-0 w-full md:w-[360px] h-screen flex flex-col bg-gradient-to-br dark:from-zinc-900 dark:to-zinc-800 from-white to-zinc-50 border-l md:border-l dark:border-zinc-700 border-zinc-300 shadow-2xl z-[100] overflow-hidden transition-all duration-300\">\r\n <div className=\"flex items-center justify-between px-4 py-3 border-b dark:border-zinc-800 border-zinc-200 dark:bg-zinc-950/80 bg-white/95 backdrop-blur-lg\">\r\n <div className=\"flex items-center gap-3\">\r\n <div className=\"relative\">\r\n <span className=\"relative w-10 h-10 block group\">\r\n <span\r\n className={`absolute inset-0 rounded-full transition-colors duration-300 ${\r\n bradyHealthy ? 'dark:bg-zinc-700/40 bg-transparent' : 'bg-red-600/80 dark:bg-red-700/80'\r\n }`}\r\n ></span>\r\n <ImageWithFallback\r\n src={avatarSrc}\r\n alt=\"Brady AI\"\r\n className=\"w-10 h-10 relative z-10\"\r\n onClick={() => setIsHidden(true)}\r\n />\r\n </span>\r\n </div>\r\n <div className=\"dark:text-white text-zinc-900\">Brady AI</div>\r\n </div>\r\n\r\n <div className=\"relative inline-flex items-center h-[34px] w-[150px] dark:bg-zinc-800/50 bg-zinc-200 rounded-full p-1\">\r\n <button\r\n onClick={() => isModeActive && resetMode()}\r\n className={`relative z-10 flex-1 h-full rounded-full text-[11px] tracking-wide uppercase font-medium transition-all duration-300 flex items-center justify-center ${\r\n !isModeActive\r\n ? 'text-white'\r\n : 'dark:text-zinc-500 text-zinc-600 hover:dark:bg-zinc-700/50 hover:bg-zinc-300/50'\r\n }`}\r\n >\r\n NORMAL\r\n </button>\r\n\r\n <div className=\"relative flex-1\">\r\n {!isModeActive && (\r\n <div\r\n className=\"absolute inset-0 rounded-full animate-pulse\"\r\n style={{\r\n boxShadow: isBranchManager\r\n ? '0 0 16px rgba(67, 153, 209, 0.6), inset 0 0 10px rgba(67, 153, 209, 0.3)'\r\n : '0 0 16px rgba(139, 92, 246, 0.6), inset 0 0 10px rgba(139, 92, 246, 0.3)',\r\n animation: 'pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite',\r\n }}\r\n />\r\n )}\r\n <button\r\n onClick={() => !isModeActive && handleFocusToggle()}\r\n className={`relative z-10 w-full h-full rounded-full text-[11px] tracking-wide uppercase font-medium transition-all duration-300 flex items-center justify-center ${\r\n isModeActive\r\n ? 'text-white'\r\n : 'dark:text-zinc-500 text-zinc-600 hover:dark:bg-zinc-700/50 hover:bg-zinc-300/50'\r\n }`}\r\n >\r\n {isBranchManager ? 'PROFIT' : 'EARNINGS'}\r\n </button>\r\n </div>\r\n\r\n <div\r\n className={`absolute top-1 bottom-1 rounded-full transition-all duration-300 ${\r\n isModeActive ? 'left-[50%] right-1' : 'left-1 right-[50%]'\r\n }`}\r\n style={\r\n isModeActive\r\n ? {\r\n background: isBranchManager\r\n ? 'linear-gradient(135deg, #4399D1 0%, #3b82d9 100%)'\r\n : 'linear-gradient(135deg, #8B5CF6 0%, #7C3AED 100%)',\r\n boxShadow: isBranchManager\r\n ? '0 0 16px rgba(67, 153, 209, 0.15)'\r\n : '0 0 16px rgba(139, 92, 246, 0.15)',\r\n }\r\n : {\r\n background: 'var(--tw-gradient-stops)',\r\n backgroundImage: 'linear-gradient(135deg, rgb(82, 82, 91) 0%, rgb(63, 63, 70) 100%)',\r\n }\r\n }\r\n />\r\n </div>\r\n </div>\r\n\r\n {modeBadge && (\r\n <div className=\"px-4 py-2 border-b dark:border-zinc-800 border-zinc-200\">\r\n {modeBadge}\r\n </div>\r\n )}\r\n\r\n {!bradyHealthy && (\r\n\r\n <div className=\"fixed top-0 right-0 w-full md:w-[360px] h-screen flex flex-col bg-gradient-to-br dark:from-zinc-900 dark:to-zinc-800 from-white to-zinc-50 border-l md:border-l dark:border-zinc-700 border-zinc-300 shadow-2xl z-[100] overflow-hidden transition-all duration-300 items-center justify-center\">\r\n <div className=\"text-center text-zinc-500 dark:text-zinc-400 text-lg font-medium\">\r\n Sorry, Brady AI is currently unavailable.\r\n </div>\r\n </div>\r\n )}\r\n <div className=\"flex-1 overflow-y-auto p-4 space-y-4\">\r\n <AnimatePresence>\r\n {messages.map((msg, idx) => (\r\n <motion.div\r\n key={idx}\r\n initial={{ opacity: 0, y: 10 }}\r\n animate={{ opacity: 1, y: 0 }}\r\n className={`flex ${msg.type === 'user' ? 'justify-end' : 'justify-start'}`}\r\n >\r\n <div\r\n className={`px-4 py-3 rounded-2xl whitespace-pre-line ${\r\n msg.type === 'user'\r\n ? 'bg-[#8B5CF6] text-white rounded-br-sm'\r\n : 'dark:bg-zinc-800 bg-zinc-100 dark:text-zinc-100 text-zinc-900 rounded-bl-sm'\r\n }`}\r\n >\r\n {msg.text === 'introduce' ? '' : msg.text}\r\n </div>\r\n </motion.div>\r\n ))}\r\n </AnimatePresence>\r\n\r\n {showForm && workflowType === 'info-request' && (\r\n <InfoRequestForm onSubmit={handleInfoFormSubmit} onCancel={handleFormCancel} />\r\n )}\r\n\r\n {showForm && workflowType === 'leadership-call' && (\r\n <LeadershipCallForm onSubmit={handleLeadershipFormSubmit} onCancel={handleFormCancel} />\r\n )}\r\n\r\n {showForm && workflowType === 'personalized-overview-request' && (\r\n <PersonalizedOverviewForm\r\n onSubmit={handlePersonalizedOverviewFormSubmit}\r\n onCancel={handleFormCancel}\r\n />\r\n )}\r\n\r\n {showModePrompts && activeMode !== 'none' && (\r\n <ModePromptTree\r\n mode={activeMode as 'earnings' | 'profit'}\r\n step={modeStep}\r\n hasPersonalizedData={hasPersonalizedData}\r\n onResponse={handleModeResponse}\r\n />\r\n )}\r\n\r\n {!showForm &&\r\n !showModePrompts &&\r\n messages.length === 1 &&\r\n workflowType === 'free' &&\r\n activeMode === 'none' && <QuickSuggestions suggestions={initialSuggestions} />}\r\n\r\n {showPostSubmitSuggestions && !showModePrompts && (\r\n <QuickSuggestions suggestions={postSubmitSuggestions} />\r\n )}\r\n\r\n <div ref={messagesEndRef} />\r\n </div>\r\n\r\n <div className=\"p-4 border-t dark:border-zinc-800 border-zinc-200 dark:bg-zinc-900 bg-zinc-50\">\r\n <div\r\n className={`flex items-center gap-2 dark:bg-zinc-800 bg-white rounded-full px-4 py-3 border dark:border-zinc-700 border-zinc-300 focus-within:border-[#8B5CF6] transition-colors ${\r\n inputDisabled || showModePrompts ? 'opacity-50 cursor-not-allowed' : ''\r\n }`}\r\n >\r\n <input\r\n type=\"text\"\r\n value={inputValue}\r\n onChange={(e) => setInputValue(e.target.value)}\r\n onKeyPress={(e) => e.key === 'Enter' && handleSend()}\r\n placeholder={\r\n inputDisabled || showModePrompts ? 'Use buttons above...' : 'Ask me anything...'\r\n }\r\n disabled={inputDisabled || showModePrompts}\r\n className=\"flex-1 bg-transparent dark:text-white text-zinc-900 dark:placeholder-zinc-500 placeholder-zinc-400 outline-none text-sm disabled:cursor-not-allowed\"\r\n />\r\n <button\r\n className=\"dark:text-zinc-400 text-zinc-500 dark:hover:text-white hover:text-zinc-900 transition-colors disabled:opacity-50\"\r\n disabled={inputDisabled || showModePrompts}\r\n >\r\n <Mic className=\"w-5 h-5\" />\r\n </button>\r\n <button\r\n onClick={handleSend}\r\n disabled={inputDisabled || showModePrompts}\r\n className=\"bg-[#8B5CF6] hover:bg-[#7C3AED] text-white rounded-full p-2 transition-colors disabled:opacity-50 disabled:cursor-not-allowed\"\r\n >\r\n <Send className=\"w-4 h-4\" />\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\n","// afnBradyApi.ts (library version)\r\n// Utility for integrating with AFN Brady Jr API\r\n\r\n// Use environment variable for API key\r\n// Supports both server (BRADY_API_KEY, BRADY_API_URL) and browser (NEXT_PUBLIC_BRADY_API_KEY, NEXT_PUBLIC_BRADY_API_URL)\r\n// Consumers: Set NEXT_PUBLIC_BRADY_API_KEY and NEXT_PUBLIC_BRADY_API_URL in your app's .env.local for browser use\r\nexport const DEFAULT_BRADY_API_KEY =\r\n typeof process !== 'undefined' && process.env && (\r\n process.env.BRADY_API_KEY || process.env.NEXT_PUBLIC_BRADY_API_KEY\r\n )\r\n ? process.env.BRADY_API_KEY || process.env.NEXT_PUBLIC_BRADY_API_KEY\r\n : 'za2345DDDzXycXKHJvVj80TIsPgooB7iNbwcS9KLzoeaOljlXmJQQJ99BJAC4f1cMXJ3w3AAABACOGQzXz';\r\n\r\nexport const API_URL =\r\n typeof process !== 'undefined' && process.env && (\r\n process.env.BRADY_API_URL || process.env.NEXT_PUBLIC_BRADY_API_URL\r\n )\r\n ? process.env.BRADY_API_URL || process.env.NEXT_PUBLIC_BRADY_API_URL\r\n : 'https://afn-bradyjr-api-dev.azurewebsites.net/';\r\n\r\nexport interface BradyMessage {\r\n role: 'user' | 'assistant' | 'system';\r\n content: string;\r\n}\r\n\r\nexport interface BradyChatRequest {\r\n messages: BradyMessage[];\r\n}\r\n\r\nexport interface BradyChatResponse {\r\n role: string;\r\n type: string;\r\n content: string;\r\n suggestionLink?: { text: string; prompt: string }[];\r\n}\r\n\r\nexport async function sendBradyPrompt(\r\n messages: BradyMessage[],\r\n apiKey: string = DEFAULT_BRADY_API_KEY\r\n): Promise<BradyChatResponse> {\r\n\r\n console.log('[DEFAULT_BRADY_API_KEY]', DEFAULT_BRADY_API_KEY);\r\n console.log('[API_URL]', API_URL);\r\n\r\n const res = await fetch(`${API_URL}/api/chat/prompt`, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'X-API-KEY': apiKey\r\n },\r\n body: JSON.stringify({ messages })\r\n });\r\n if (!res.ok) throw new Error('Brady API error: ' + res.status);\r\n const data = await res.json();\r\n if (process.env.NODE_ENV === 'development') {\r\n // eslint-disable-next-line no-console\r\n console.log('[Brady API Response]', data);\r\n }\r\n return data;\r\n}\r\n\r\n","// bradyHealth.ts (library version)\r\n// Utility to check health of Brady AI API\r\n\r\nimport { API_URL } from './afnBradyApi';\r\n\r\nexport async function checkBradyHealth(): Promise<boolean> {\r\n try {\r\n const res = await fetch(`${API_URL}/api/Health`);\r\n if (!res.ok) return false;\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\n","'use client';\r\n\r\nimport React, { useState } from 'react';\r\nimport { motion } from 'motion/react';\r\n\r\ninterface InfoRequestFormProps {\r\n onSubmit: (data: { firstName: string; lastName: string; email: string; phone?: string }) => void;\r\n onCancel: () => void;\r\n}\r\n\r\nexport function InfoRequestForm({ onSubmit, onCancel }: InfoRequestFormProps) {\r\n const [formData, setFormData] = useState({\r\n firstName: '',\r\n lastName: '',\r\n email: '',\r\n phone: '',\r\n });\r\n const [errors, setErrors] = useState<Record<string, string>>({});\r\n\r\n const handleSubmit = (e: React.FormEvent) => {\r\n e.preventDefault();\r\n const newErrors: Record<string, string> = {};\r\n\r\n if (!formData.firstName.trim()) {\r\n newErrors.firstName = 'First name is required';\r\n }\r\n if (!formData.lastName.trim()) {\r\n newErrors.lastName = 'Last name is required';\r\n }\r\n if (!formData.email.trim()) {\r\n newErrors.email = 'Email is required';\r\n } else if (!/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(formData.email)) {\r\n newErrors.email = 'Please enter a valid email address';\r\n }\r\n\r\n if (Object.keys(newErrors).length > 0) {\r\n setErrors(newErrors);\r\n return;\r\n }\r\n\r\n onSubmit(formData);\r\n };\r\n\r\n return (\r\n <motion.div\r\n initial={{ opacity: 0, y: 10 }}\r\n animate={{ opacity: 1, y: 0 }}\r\n className=\"bg-gradient-to-br from-white to-zinc-50 dark:from-zinc-800 dark:to-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-2xl p-6 max-h-[360px]\"\r\n >\r\n <h3 className=\"text-lg text-zinc-900 dark:text-white mb-4\">Send Me More Information</h3>\r\n\r\n <form onSubmit={handleSubmit} className=\"space-y-3\">\r\n <div>\r\n <input\r\n type=\"text\"\r\n placeholder=\"First Name\"\r\n value={formData.firstName}\r\n onChange={(e) => setFormData({ ...formData, firstName: e.target.value })}\r\n className=\"w-full px-4 py-2.5 bg-white dark:bg-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-lg text-zinc-900 dark:text-white placeholder-zinc-500 focus:border-[#8B5CF6] focus:outline-none transition-colors\"\r\n />\r\n {errors.firstName && <p className=\"text-red-500 text-xs mt-1\">{errors.firstName}</p>}\r\n </div>\r\n\r\n <div>\r\n <input\r\n type=\"text\"\r\n placeholder=\"Last Name\"\r\n value={formData.lastName}\r\n onChange={(e) => setFormData({ ...formData, lastName: e.target.value })}\r\n className=\"w-full px-4 py-2.5 bg-white dark:bg-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-lg text-zinc-900 dark:text-white placeholder-zinc-500 focus:border-[#8B5CF6] focus:outline-none transition-colors\"\r\n />\r\n {errors.lastName && <p className=\"text-red-500 text-xs mt-1\">{errors.lastName}</p>}\r\n </div>\r\n\r\n <div>\r\n <input\r\n type=\"email\"\r\n placeholder=\"Email Address\"\r\n value={formData.email}\r\n onChange={(e) => setFormData({ ...formData, email: e.target.value })}\r\n className=\"w-full px-4 py-2.5 bg-white dark:bg-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-lg text-zinc-900 dark:text-white placeholder-zinc-500 focus:border-[#8B5CF6] focus:outline-none transition-colors\"\r\n />\r\n {errors.email && <p className=\"text-red-500 text-xs mt-1\">{errors.email}</p>}\r\n </div>\r\n\r\n <div>\r\n <input\r\n type=\"tel\"\r\n placeholder=\"Phone (optional)\"\r\n value={formData.phone}\r\n onChange={(e) => setFormData({ ...formData, phone: e.target.value })}\r\n className=\"w-full px-4 py-2.5 bg-white dark:bg-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-lg text-zinc-900 dark:text-white placeholder-zinc-500 focus:border-[#8B5CF6] focus:outline-none transition-colors\"\r\n />\r\n </div>\r\n\r\n <div className=\"flex gap-2 pt-2\">\r\n <button\r\n type=\"submit\"\r\n className=\"flex-1 bg-[#8B5CF6] hover:bg-[#7C3AED] text-white py-2.5 rounded-lg transition-colors\"\r\n >\r\n Send Information\r\n </button>\r\n <button\r\n type=\"button\"\r\n onClick={onCancel}\r\n className=\"px-4 text-zinc-600 dark:text-zinc-400 hover:text-zinc-900 dark:hover:text-white transition-colors\"\r\n >\r\n Cancel\r\n </button>\r\n </div>\r\n </form>\r\n </motion.div>\r\n );\r\n}\r\n\r\n","'use client';\r\n\r\nimport React, { useState } from 'react';\r\nimport { motion } from 'motion/react';\r\nimport { Calendar, Clock } from 'lucide-react';\r\n\r\ninterface LeadershipCallFormProps {\r\n onSubmit: (data: {\r\n firstName: string;\r\n lastName: string;\r\n email: string;\r\n phone: string;\r\n preferredDate?: string;\r\n preferredTime?: string;\r\n }) => void;\r\n onCancel: () => void;\r\n}\r\n\r\nexport function LeadershipCallForm({ onSubmit, onCancel }: LeadershipCallFormProps) {\r\n const [formData, setFormData] = useState({\r\n firstName: '',\r\n lastName: '',\r\n email: '',\r\n phone: '',\r\n preferredDate: '',\r\n preferredTime: '',\r\n });\r\n const [errors, setErrors] = useState<Record<string, string>>({});\r\n\r\n const handleSubmit = (e: React.FormEvent) => {\r\n e.preventDefault();\r\n const newErrors: Record<string, string> = {};\r\n\r\n if (!formData.firstName.trim()) {\r\n newErrors.firstName = 'First name is required';\r\n }\r\n if (!formData.lastName.trim()) {\r\n newErrors.lastName = 'Last name is required';\r\n }\r\n if (!formData.email.trim()) {\r\n newErrors.email = 'Email is required';\r\n } else if (!/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(formData.email)) {\r\n newErrors.email = 'Please enter a valid email address';\r\n }\r\n if (!formData.phone.trim()) {\r\n newErrors.phone = 'Phone number is required';\r\n }\r\n\r\n if (Object.keys(newErrors).length > 0) {\r\n setErrors(newErrors);\r\n return;\r\n }\r\n\r\n onSubmit(formData);\r\n };\r\n\r\n const timeSlots = ['Morning (8am - 12pm)', 'Afternoon (12pm - 5pm)', 'Evening (5pm - 8pm)'];\r\n\r\n return (\r\n <motion.div\r\n initial={{ opacity: 0, y: 10 }}\r\n animate={{ opacity: 1, y: 0 }}\r\n className=\"bg-gradient-to-br from-white to-zinc-50 dark:from-zinc-800 dark:to-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-2xl p-6\"\r\n >\r\n <h3 className=\"text-lg text-zinc-900 dark:text-white mb-4\">Talk to AFN Leadership</h3>\r\n\r\n <form onSubmit={handleSubmit} className=\"space-y-3\">\r\n <div>\r\n <input\r\n type=\"text\"\r\n placeholder=\"First Name\"\r\n value={formData.firstName}\r\n onChange={(e) => setFormData({ ...formData, firstName: e.target.value })}\r\n className=\"w-full px-4 py-2.5 bg-white dark:bg-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-lg text-zinc-900 dark:text-white placeholder-zinc-500 focus:border-[#8B5CF6] focus:outline-none transition-colors\"\r\n />\r\n {errors.firstName && <p className=\"text-red-500 text-xs mt-1\">{errors.firstName}</p>}\r\n </div>\r\n\r\n <div>\r\n <input\r\n type=\"text\"\r\n placeholder=\"Last Name\"\r\n value={formData.lastName}\r\n onChange={(e) => setFormData({ ...formData, lastName: e.target.value })}\r\n className=\"w-full px-4 py-2.5 bg-white dark:bg-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-lg text-zinc-900 dark:text-white placeholder-zinc-500 focus:border-[#8B5CF6] focus:outline-none transition-colors\"\r\n />\r\n {errors.lastName && <p className=\"text-red-500 text-xs mt-1\">{errors.lastName}</p>}\r\n </div>\r\n\r\n <div>\r\n <input\r\n type=\"email\"\r\n placeholder=\"Email Address\"\r\n value={formData.email}\r\n onChange={(e) => setFormData({ ...formData, email: e.target.value })}\r\n className=\"w-full px-4 py-2.5 bg-white dark:bg-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-lg text-zinc-900 dark:text-white placeholder-zinc-500 focus:border-[#8B5CF6] focus:outline-none transition-colors\"\r\n />\r\n {errors.email && <p className=\"text-red-500 text-xs mt-1\">{errors.email}</p>}\r\n </div>\r\n\r\n <div>\r\n <input\r\n type=\"tel\"\r\n placeholder=\"Phone Number\"\r\n value={formData.phone}\r\n onChange={(e) => setFormData({ ...formData, phone: e.target.value })}\r\n className=\"w-full px-4 py-2.5 bg-white dark:bg-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-lg text-zinc-900 dark:text-white placeholder-zinc-500 focus:border-[#8B5CF6] focus:outline-none transition-colors\"\r\n />\r\n {errors.phone && <p className=\"text-red-500 text-xs mt-1\">{errors.phone}</p>}\r\n </div>\r\n\r\n <div className=\"pt-2 border-t border-zinc-200 dark:border-zinc-700\">\r\n <p className=\"text-sm text-zinc-600 dark:text-zinc-400 mb-2\">Preferred Call Time (optional)</p>\r\n <div className=\"grid grid-cols-2 gap-2\">\r\n <div className=\"relative\">\r\n <Calendar className=\"pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-zinc-500\" />\r\n <input\r\n type=\"date\"\r\n value={formData.preferredDate}\r\n onChange={(e) => setFormData({ ...formData, preferredDate: e.target.value })}\r\n className=\"w-full pl-12 pr-4 py-2.5 bg-white dark:bg-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-lg text-zinc-900 dark:text-white text-sm focus:border-[#8B5CF6] focus:outline-none transition-colors\"\r\n />\r\n </div>\r\n <div className=\"relative\">\r\n <Clock className=\"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-zinc-500\" />\r\n <select\r\n value={formData.preferredTime}\r\n onChange={(e) => setFormData({ ...formData, preferredTime: e.target.value })}\r\n className=\"w-full pl-10 pr-4 py-2.5 bg-white dark:bg-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-lg text-zinc-900 dark:text-white text-sm focus:border-[#8B5CF6] focus:outline-none transition-colors appearance-none\"\r\n >\r\n <option value=\"\">Select time</option>\r\n {timeSlots.map((slot) => (\r\n <option key={slot} value={slot}>\r\n {slot}\r\n </option>\r\n ))}\r\n </select>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div className=\"flex gap-2 pt-2\">\r\n <button\r\n type=\"submit\"\r\n className=\"flex-1 bg-[#8B5CF6] hover:bg-[#7C3AED] text-white py-2.5 rounded-lg transition-colors\"\r\n >\r\n Request Call\r\n </button>\r\n <button\r\n type=\"button\"\r\n onClick={onCancel}\r\n className=\"px-4 text-zinc-600 dark:text-zinc-400 hover:text-zinc-900 dark:hover:text-white transition-colors\"\r\n >\r\n Cancel\r\n </button>\r\n </div>\r\n </form>\r\n </motion.div>\r\n );\r\n}\r\n\r\n","'use client';\r\n\r\nimport React, { useState } from 'react';\r\nimport { motion } from 'motion/react';\r\n\r\ninterface PersonalizedOverviewFormProps {\r\n onSubmit: (data: {\r\n firstName: string;\r\n lastName: string;\r\n email: string;\r\n phone?: string;\r\n nmlsId?: string;\r\n }) => void;\r\n onCancel: () => void;\r\n}\r\n\r\nexport function PersonalizedOverviewForm({ onSubmit, onCancel }: PersonalizedOverviewFormProps) {\r\n const [formData, setFormData] = useState({\r\n firstName: '',\r\n lastName: '',\r\n email: '',\r\n phone: '',\r\n nmlsId: '',\r\n });\r\n const [errors, setErrors] = useState<Record<string, string>>({});\r\n\r\n const handleSubmit = (e: React.FormEvent) => {\r\n e.preventDefault();\r\n const newErrors: Record<string, string> = {};\r\n\r\n if (!formData.firstName.trim()) {\r\n newErrors.firstName = 'First name is required';\r\n }\r\n if (!formData.lastName.trim()) {\r\n newErrors.lastName = 'Last name is required';\r\n }\r\n if (!formData.email.trim()) {\r\n newErrors.email = 'Email is required';\r\n } else if (!/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(formData.email)) {\r\n newErrors.email = 'Please enter a valid email address';\r\n }\r\n\r\n if (Object.keys(newErrors).length > 0) {\r\n setErrors(newErrors);\r\n return;\r\n }\r\n\r\n onSubmit(formData);\r\n };\r\n\r\n return (\r\n <motion.div\r\n initial={{ opacity: 0, y: 10 }}\r\n animate={{ opacity: 1, y: 0 }}\r\n className=\"bg-gradient-to-br from-white to-zinc-50 dark:from-zinc-800 dark:to-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-2xl p-6\"\r\n >\r\n <h3 className=\"text-lg text-zinc-900 dark:text-white mb-4\">Request Personalized Overview</h3>\r\n\r\n <form onSubmit={handleSubmit} className=\"space-y-3\">\r\n <div>\r\n <input\r\n type=\"text\"\r\n placeholder=\"First Name\"\r\n value={formData.firstName}\r\n onChange={(e) => setFormData({ ...formData, firstName: e.target.value })}\r\n className=\"w-full px-4 py-2.5 bg-white dark:bg-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-lg text-zinc-900 dark:text-white placeholder-zinc-500 focus:border-[#8B5CF6] focus:outline-none transition-colors\"\r\n />\r\n {errors.firstName && <p className=\"text-red-500 text-xs mt-1\">{errors.firstName}</p>}\r\n </div>\r\n\r\n <div>\r\n <input\r\n type=\"text\"\r\n placeholder=\"Last Name\"\r\n value={formData.lastName}\r\n onChange={(e) => setFormData({ ...formData, lastName: e.target.value })}\r\n className=\"w-full px-4 py-2.5 bg-white dark:bg-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-lg text-zinc-900 dark:text-white placeholder-zinc-500 focus:border-[#8B5CF6] focus:outline-none transition-colors\"\r\n />\r\n {errors.lastName && <p className=\"text-red-500 text-xs mt-1\">{errors.lastName}</p>}\r\n </div>\r\n\r\n <div>\r\n <input\r\n type=\"email\"\r\n placeholder=\"Email Address\"\r\n value={formData.email}\r\n onChange={(e) => setFormData({ ...formData, email: e.target.value })}\r\n className=\"w-full px-4 py-2.5 bg-white dark:bg-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-lg text-zinc-900 dark:text-white placeholder-zinc-500 focus:border-[#8B5CF6] focus:outline-none transition-colors\"\r\n />\r\n {errors.email && <p className=\"text-red-500 text-xs mt-1\">{errors.email}</p>}\r\n </div>\r\n\r\n <div>\r\n <input\r\n type=\"tel\"\r\n placeholder=\"Phone (optional)\"\r\n value={formData.phone}\r\n onChange={(e) => setFormData({ ...formData, phone: e.target.value })}\r\n className=\"w-full px-4 py-2.5 bg-white dark:bg-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-lg text-zinc-900 dark:text-white placeholder-zinc-500 focus:border-[#8B5CF6] focus:outline-none transition-colors\"\r\n />\r\n </div>\r\n\r\n <div>\r\n <input\r\n type=\"text\"\r\n placeholder=\"NMLS ID (optional)\"\r\n value={formData.nmlsId}\r\n onChange={(e) => setFormData({ ...formData, nmlsId: e.target.value })}\r\n className=\"w-full px-4 py-2.5 bg-white dark:bg-zinc-900 border border-zinc-300 dark:border-zinc-700 rounded-lg text-zinc-900 dark:text-white placeholder-zinc-500 focus:border-[#8B5CF6] focus:outline-none transition-colors\"\r\n />\r\n </div>\r\n\r\n <div className=\"flex gap-2 pt-2\">\r\n <button\r\n type=\"submit\"\r\n className=\"flex-1 bg-[#8B5CF6] hover:bg-[#7C3AED] text-white py-2.5 rounded-lg transition-colors\"\r\n >\r\n Request Overview\r\n </button>\r\n <button\r\n type=\"button\"\r\n onClick={onCancel}\r\n className=\"px-4 text-zinc-600 dark:text-zinc-400 hover:text-zinc-900 dark:hover:text-white transition-colors\"\r\n >\r\n Cancel\r\n </button>\r\n </div>\r\n </form>\r\n </motion.div>\r\n );\r\n}\r\n\r\n","'use client';\r\n\r\nimport { motion } from 'motion/react';\r\n\r\ninterface QuickSuggestion {\r\n text: string;\r\n action: () => void;\r\n}\r\n\r\ninterface QuickSuggestionsProps {\r\n suggestions: QuickSuggestion[];\r\n}\r\n\r\nexport function QuickSuggestions({ suggestions }: QuickSuggestionsProps) {\r\n return (\r\n <motion.div\r\n initial={{ opacity: 0, y: 10 }}\r\n animate={{ opacity: 1, y: 0 }}\r\n className=\"flex flex-wrap gap-2\"\r\n >\r\n {suggestions.map((suggestion, idx) => (\r\n <button\r\n key={idx}\r\n onClick={suggestion.action}\r\n className=\"px-3 py-1.5 bg-zinc-100 dark:bg-zinc-800 hover:bg-zinc-200 dark:hover:bg-zinc-700 text-zinc-700 dark:text-zinc-300 text-sm rounded-full border border-zinc-300 dark:border-zinc-700 transition-colors\"\r\n >\r\n {suggestion.text}\r\n </button>\r\n ))}\r\n </motion.div>\r\n );\r\n}\r\n\r\n","'use client';\r\n\r\nimport { motion } from 'motion/react';\r\n\r\ninterface ModePromptTreeProps {\r\n mode: 'earnings' | 'profit';\r\n step: string;\r\n hasPersonalizedData: boolean;\r\n onResponse: (response: string, data?: any) => void;\r\n}\r\n\r\nexport function ModePromptTree({ mode, step, hasPersonalizedData, onResponse }: ModePromptTreeProps) {\r\n if (mode === 'earnings') {\r\n if (step === 'volume') {\r\n if (hasPersonalizedData) {\r\n return (\r\n <motion.div initial={{ opacity: 0, y: 10 }} animate={{ opacity: 1, y: 0 }} className=\"space-y-3\">\r\n <div className=\"grid grid-cols-1 gap-2\">\r\n <button\r\n onClick={() => onResponse('yes', { volumeMultiplier: 1.0 })}\r\n className=\"px-4 py-3 bg-[#8B5CF6] hover:bg-[#7C3AED] text-white rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Yes, that's about right\r\n </button>\r\n <button\r\n onClick={() => onResponse('higher', { volumeMultiplier: 1.1 })}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n It's a bit higher\r\n </button>\r\n <button\r\n onClick={() => onResponse('lower', { volumeMultiplier: 0.9 })}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n It's a bit lower\r\n </button>\r\n </div>\r\n </motion.div>\r\n );\r\n }\r\n\r\n return (\r\n <motion.div initial={{ opacity: 0, y: 10 }} animate={{ opacity: 1, y: 0 }} className=\"space-y-3\">\r\n <div className=\"grid grid-cols-1 gap-2\">\r\n <button\r\n onClick={() => onResponse('Under $500k', { volume: 400000 })}\r\n className=\"px-4 py-3 bg-[#8B5CF6] hover:bg-[#7C3AED] text-white rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Under $500k\r\n </button>\r\n <button\r\n onClick={() => onResponse('$500k – $1M', { volume: 750000 })}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n $500k – $1M\r\n </button>\r\n <button\r\n onClick={() => onResponse('$1M – $2M', { volume: 1500000 })}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n $1M – $2M\r\n </button>\r\n <button\r\n onClick={() => onResponse('$2M+', { volume: 2500000 })}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n $2M+\r\n </button>\r\n </div>\r\n </motion.div>\r\n );\r\n }\r\n\r\n if (step === 'comp') {\r\n return (\r\n <motion.div initial={{ opacity: 0, y: 10 }} animate={{ opacity: 1, y: 0 }} className=\"space-y-3\">\r\n <div className=\"grid grid-cols-1 gap-2\">\r\n <button\r\n onClick={() => onResponse('Under 100 bps', { comp: 0.95 })}\r\n className=\"px-4 py-3 bg-[#8B5CF6] hover:bg-[#7C3AED] text-white rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Under 100 bps\r\n </button>\r\n <button\r\n onClick={() => onResponse('Around 125 bps', { comp: 1.25 })}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Around 125 bps\r\n </button>\r\n <button\r\n onClick={() => onResponse('150+ bps', { comp: 1.5 })}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n 150+ bps\r\n </button>\r\n <button\r\n onClick={() => onResponse(\"I'm not sure\", { comp: 1.15 })}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n I'm not sure\r\n </button>\r\n </div>\r\n </motion.div>\r\n );\r\n }\r\n\r\n if (step === 'complete') {\r\n return (\r\n <motion.div initial={{ opacity: 0, y: 10 }} animate={{ opacity: 1, y: 0 }} className=\"space-y-3\">\r\n <div className=\"grid grid-cols-1 gap-2\">\r\n <button\r\n onClick={() => onResponse('Talk through this with AFN')}\r\n className=\"px-4 py-3 bg-[#8B5CF6] hover:bg-[#7C3AED] text-white rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Talk through this with AFN\r\n </button>\r\n <button\r\n onClick={() => onResponse('Adjust the numbers')}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Adjust the numbers\r\n </button>\r\n <button\r\n onClick={() => onResponse('Keep exploring')}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Keep exploring\r\n </button>\r\n </div>\r\n </motion.div>\r\n );\r\n }\r\n }\r\n\r\n if (mode === 'profit') {\r\n if (step === 'volume') {\r\n if (hasPersonalizedData) {\r\n return (\r\n <motion.div initial={{ opacity: 0, y: 10 }} animate={{ opacity: 1, y: 0 }} className=\"space-y-3\">\r\n <div className=\"grid grid-cols-1 gap-2\">\r\n <button\r\n onClick={() => onResponse('Yes', { volumeMultiplier: 1.0 })}\r\n className=\"px-4 py-3 bg-[#4399D1] hover:bg-[#2B7AB8] text-white rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Yes\r\n </button>\r\n <button\r\n onClick={() => onResponse('Volume is higher', { volumeMultiplier: 1.1 })}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Volume is higher\r\n </button>\r\n <button\r\n onClick={() => onResponse('Volume is lower', { volumeMultiplier: 0.9 })}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Volume is lower\r\n </button>\r\n </div>\r\n </motion.div>\r\n );\r\n }\r\n\r\n return (\r\n <motion.div initial={{ opacity: 0, y: 10 }} animate={{ opacity: 1, y: 0 }} className=\"space-y-3\">\r\n <div className=\"grid grid-cols-1 gap-2\">\r\n <button\r\n onClick={() => onResponse('Under $100M', { volume: 75000000 })}\r\n className=\"px-4 py-3 bg-[#4399D1] hover:bg-[#2B7AB8] text-white rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Under $100M\r\n </button>\r\n <button\r\n onClick={() => onResponse('$100M – $250M', { volume: 175000000 })}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n $100M – $250M\r\n </button>\r\n <button\r\n onClick={() => onResponse('$250M – $500M', { volume: 375000000 })}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n $250M – $500M\r\n </button>\r\n <button\r\n onClick={() => onResponse('$500M+', { volume: 650000000 })}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n $500M+\r\n </button>\r\n </div>\r\n </motion.div>\r\n );\r\n }\r\n\r\n if (step === 'economics') {\r\n return (\r\n <motion.div initial={{ opacity: 0, y: 10 }} animate={{ opacity: 1, y: 0 }} className=\"space-y-3\">\r\n <div className=\"grid grid-cols-1 gap-2\">\r\n <button\r\n onClick={() => onResponse('Sounds right', { margin: 3.0, grossProfit: 1.5, opEx: 0.75 })}\r\n className=\"px-4 py-3 bg-[#4399D1] hover:bg-[#2B7AB8] text-white rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Sounds right\r\n </button>\r\n <button\r\n onClick={() =>\r\n onResponse('Margin is higher', {\r\n margin: 3.5,\r\n grossProfit: 1.75,\r\n opEx: 0.75,\r\n })\r\n }\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Margin is higher\r\n </button>\r\n <button\r\n onClick={() =>\r\n onResponse('Expenses are higher', {\r\n margin: 3.0,\r\n grossProfit: 1.5,\r\n opEx: 0.95,\r\n })\r\n }\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Expenses are higher\r\n </button>\r\n <button\r\n onClick={() =>\r\n onResponse('Let me adjust', {\r\n margin: 3.0,\r\n grossProfit: 1.5,\r\n opEx: 0.75,\r\n })\r\n }\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Let me adjust\r\n </button>\r\n </div>\r\n </motion.div>\r\n );\r\n }\r\n\r\n if (step === 'complete') {\r\n return (\r\n <motion.div initial={{ opacity: 0, y: 10 }} animate={{ opacity: 1, y: 0 }} className=\"space-y-3\">\r\n <div className=\"grid grid-cols-1 gap-2\">\r\n <button\r\n onClick={() => onResponse('Sanity-check with AFN')}\r\n className=\"px-4 py-3 bg-[#4399D1] hover:bg-[#2B7AB8] text-white rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Sanity-check with AFN\r\n </button>\r\n <button\r\n onClick={() => onResponse('Adjust assumptions')}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Adjust assumptions\r\n </button>\r\n <button\r\n onClick={() => onResponse('Schedule leadership call')}\r\n className=\"px-4 py-3 dark:bg-zinc-800 bg-zinc-100 dark:hover:bg-zinc-700 hover:bg-zinc-200 dark:text-white text-zinc-900 rounded-lg text-sm transition-colors text-left\"\r\n >\r\n Schedule leadership call\r\n </button>\r\n </div>\r\n </motion.div>\r\n );\r\n }\r\n }\r\n\r\n return null;\r\n}\r\n\r\n","import React, { useState } from 'react';\r\n\r\nconst ERROR_IMG_SRC =\r\n 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iODgiIGhlaWdodD0iODgiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBvcGFjaXR5PSIuMyIgZmlsbD0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIzLjciPjxyZWN0IHg9IjE2IiB5PSIxNiIgd2lkdGg9IjU2IiBoZWlnaHQ9IjU2IiByeD0iNiIvPjxwYXRoIGQ9Im0xNiA1OCAxNi0xOCAzMiAzMiIvPjxjaXJjbGUgY3g9IjUzIiBjeT0iMzUiIHI9IjciLz48L3N2Zz4KCg==';\r\n\r\nexport function ImageWithFallback(props: React.ImgHTMLAttributes<HTMLImageElement>) {\r\n const [didError, setDidError] = useState(false);\r\n\r\n const handleError = () => {\r\n setDidError(true);\r\n };\r\n\r\n const { src, alt, style, className, ...rest } = props;\r\n\r\n return didError ? (\r\n <div\r\n className={`inline-block bg-gray-100 text-center align-middle ${className ?? ''}`}\r\n style={style}\r\n >\r\n <div className=\"flex items-center justify-center w-full h-full\">\r\n <img src={ERROR_IMG_SRC} alt=\"Error loading image\" {...rest} data-original-url={src} />\r\n </div>\r\n </div>\r\n ) : (\r\n <img src={src} alt={alt} className={className} style={style} {...rest} onError={handleError} />\r\n );\r\n}\r\n\r\n"],"mappings":"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","names":["useState","motion","useState","jsx","useState","motion","jsx","jsxs","useState","motion","jsx","jsxs","motion","jsx","motion","jsx","jsxs","useState","jsx","jsx","jsxs","useState","motion"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@afncdelacru/brady-chat",
3
- "version": "0.1.6",
3
+ "version": "0.1.8",
4
4
  "description": "Brady AI chat sidebar component and context for AFN recruiting experiences.",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.mjs",
@@ -32,6 +32,6 @@
32
32
  "afn"
33
33
  ],
34
34
  "dependencies": {
35
- "@afncdelacru/brady-chat": "^0.1.6"
35
+ "@afncdelacru/brady-chat": "^0.1.8"
36
36
  }
37
37
  }
@@ -56,7 +56,7 @@ const BradyChatContext = createContext<BradyChatContextType | undefined>(undefin
56
56
 
57
57
  const initialMessages: ChatMessage[] = [
58
58
  {
59
- type: 'brady',
59
+ type: 'user',
60
60
  text: "introduce",
61
61
  },
62
62
  ];
@@ -267,8 +267,9 @@ export function EnhancedBradyChat({ modeVariant = 'loan-officer', avatarSrc }: E
267
267
  const handleSend = async () => {
268
268
  if (inputValue.trim() && !inputDisabled) {
269
269
  const userText = inputValue;
270
- addMessage({ type: 'user', text: userText });
271
- setInputValue('');
270
+ addMessage({ type: 'user', text: userText });
271
+ setInputValue('');
272
+
272
273
  try {
273
274
  const apiResponse = await sendBradyPrompt([{ role: 'user', content: userText }]);
274
275
  let mappedType: 'user' | 'brady' | 'form' = 'brady';
@@ -343,36 +344,7 @@ export function EnhancedBradyChat({ modeVariant = 'loan-officer', avatarSrc }: E
343
344
  action: () => handleQuickSuggestion(s.prompt),
344
345
  }));
345
346
  }
346
- return [
347
- {
348
- text: 'How does AFN help LOs grow?',
349
- action: () => handleQuickSuggestion('How does AFN help LOs grow?'),
350
- },
351
- {
352
- text: 'How does AFN help branch managers earn more?',
353
- action: () => handleQuickSuggestion('How does AFN help branch managers earn more?'),
354
- },
355
- {
356
- text: 'Why do people choose AFN?',
357
- action: () => handleQuickSuggestion('Why do people choose AFN?'),
358
- },
359
- {
360
- text: 'The AFN Advantage',
361
- action: () => handleQuickSuggestion('See How AFN Supports Loan Officer Success'),
362
- },
363
- {
364
- text: 'Why AFN?',
365
- action: () => handleQuickSuggestion('Why AFN?'),
366
- },
367
- {
368
- text: 'How does AI help me earn more?',
369
- action: () => handleQuickSuggestion('How does AI help me earn more?'),
370
- },
371
- {
372
- text: 'What makes AFN different?',
373
- action: () => handleQuickSuggestion('What makes AFN different?'),
374
- },
375
- ];
347
+ return [];
376
348
  };
377
349
 
378
350
  const initialSuggestions = buildSuggestions();
@@ -405,15 +377,7 @@ export function EnhancedBradyChat({ modeVariant = 'loan-officer', avatarSrc }: E
405
377
  ) : null;
406
378
 
407
379
  if (isHidden) return null;
408
- if (!bradyHealthy) {
409
- return (
410
- <div className="fixed top-0 right-0 w-full md:w-[360px] h-screen flex flex-col bg-gradient-to-br dark:from-zinc-900 dark:to-zinc-800 from-white to-zinc-50 border-l md:border-l dark:border-zinc-700 border-zinc-300 shadow-2xl z-[100] overflow-hidden transition-all duration-300 items-center justify-center">
411
- <div className="text-center text-zinc-500 dark:text-zinc-400 text-lg font-medium">
412
- Sorry, Brady AI is currently unavailable.
413
- </div>
414
- </div>
415
- );
416
- }
380
+
417
381
 
418
382
  return (
419
383
  <div className="fixed top-0 right-0 w-full md:w-[360px] h-screen flex flex-col bg-gradient-to-br dark:from-zinc-900 dark:to-zinc-800 from-white to-zinc-50 border-l md:border-l dark:border-zinc-700 border-zinc-300 shadow-2xl z-[100] overflow-hidden transition-all duration-300">
@@ -502,6 +466,14 @@ export function EnhancedBradyChat({ modeVariant = 'loan-officer', avatarSrc }: E
502
466
  </div>
503
467
  )}
504
468
 
469
+ {!bradyHealthy && (
470
+
471
+ <div className="fixed top-0 right-0 w-full md:w-[360px] h-screen flex flex-col bg-gradient-to-br dark:from-zinc-900 dark:to-zinc-800 from-white to-zinc-50 border-l md:border-l dark:border-zinc-700 border-zinc-300 shadow-2xl z-[100] overflow-hidden transition-all duration-300 items-center justify-center">
472
+ <div className="text-center text-zinc-500 dark:text-zinc-400 text-lg font-medium">
473
+ Sorry, Brady AI is currently unavailable.
474
+ </div>
475
+ </div>
476
+ )}
505
477
  <div className="flex-1 overflow-y-auto p-4 space-y-4">
506
478
  <AnimatePresence>
507
479
  {messages.map((msg, idx) => (
@@ -518,7 +490,7 @@ export function EnhancedBradyChat({ modeVariant = 'loan-officer', avatarSrc }: E
518
490
  : 'dark:bg-zinc-800 bg-zinc-100 dark:text-zinc-100 text-zinc-900 rounded-bl-sm'
519
491
  }`}
520
492
  >
521
- {msg.text}
493
+ {msg.text === 'introduce' ? '' : msg.text}
522
494
  </div>
523
495
  </motion.div>
524
496
  ))}