fix: chat panel doesn't overlap main content, links use client-side nav
Layout: main content gets mr-96 (margin-right) when chat is open, pushing the page content left so the chat panel sits alongside it without overlapping. Smooth 300ms transition. ChatPanel: internal links (/products/..., /orders/...) now use React Router navigate() instead of target="_blank" — clicking a product link in the chat navigates without reloading the page, keeping the chat panel open. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
import { useState, useRef, useEffect, useCallback } from 'react'
|
import { useState, useRef, useEffect, useCallback } from 'react'
|
||||||
|
import { useNavigate } from 'react-router-dom'
|
||||||
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
|
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
|
||||||
import { MessageSquare, Send, Loader2, X, Plus, Bot, User } from 'lucide-react'
|
import { MessageSquare, Send, Loader2, X, Plus, Bot, User } from 'lucide-react'
|
||||||
import ReactMarkdown from 'react-markdown'
|
import ReactMarkdown from 'react-markdown'
|
||||||
@@ -37,6 +38,7 @@ export default function ChatPanel({ open, onClose, contextType, contextId }: Cha
|
|||||||
const messagesEndRef = useRef<HTMLDivElement>(null)
|
const messagesEndRef = useRef<HTMLDivElement>(null)
|
||||||
const inputRef = useRef<HTMLInputElement>(null)
|
const inputRef = useRef<HTMLInputElement>(null)
|
||||||
const queryClient = useQueryClient()
|
const queryClient = useQueryClient()
|
||||||
|
const navigate = useNavigate()
|
||||||
|
|
||||||
// Load sessions
|
// Load sessions
|
||||||
const { data: sessions } = useQuery({
|
const { data: sessions } = useQuery({
|
||||||
@@ -251,7 +253,13 @@ export default function ChatPanel({ open, onClose, contextType, contextId }: Cha
|
|||||||
ol: ({ children }) => <ol className="list-decimal list-inside mb-1 space-y-0.5">{children}</ol>,
|
ol: ({ children }) => <ol className="list-decimal list-inside mb-1 space-y-0.5">{children}</ol>,
|
||||||
li: ({ children }) => <li>{children}</li>,
|
li: ({ children }) => <li>{children}</li>,
|
||||||
code: ({ children }) => <code className="px-1 py-0.5 rounded text-xs font-mono" style={{ backgroundColor: 'var(--color-bg-muted)' }}>{children}</code>,
|
code: ({ children }) => <code className="px-1 py-0.5 rounded text-xs font-mono" style={{ backgroundColor: 'var(--color-bg-muted)' }}>{children}</code>,
|
||||||
a: ({ href, children }) => <a href={href} target="_blank" rel="noopener noreferrer" className="text-accent underline hover:text-accent-hover">{children}</a>,
|
a: ({ href, children }) => {
|
||||||
|
const isInternal = href?.startsWith('/products/') || href?.startsWith('/orders/')
|
||||||
|
if (isInternal) {
|
||||||
|
return <a href={href} onClick={(e) => { e.preventDefault(); navigate(href!) }} className="text-accent underline hover:text-accent-hover cursor-pointer">{children}</a>
|
||||||
|
}
|
||||||
|
return <a href={href} target="_blank" rel="noopener noreferrer" className="text-accent underline hover:text-accent-hover">{children}</a>
|
||||||
|
},
|
||||||
img: ({ src, alt }) => <img src={src} alt={alt || 'render'} className="max-w-full rounded-lg mt-1 mb-1 border border-border-default" style={{ maxHeight: '200px' }} />,
|
img: ({ src, alt }) => <img src={src} alt={alt || 'render'} className="max-w-full rounded-lg mt-1 mb-1 border border-border-default" style={{ maxHeight: '200px' }} />,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -254,8 +254,8 @@ export default function Layout() {
|
|||||||
</div>
|
</div>
|
||||||
</aside>
|
</aside>
|
||||||
|
|
||||||
{/* Main content */}
|
{/* Main content — shrinks when chat panel is open */}
|
||||||
<main className="flex-1 overflow-auto min-w-0 pt-12 md:pt-0">
|
<main className={`flex-1 overflow-auto min-w-0 pt-12 md:pt-0 transition-all duration-300 ${chatOpen ? 'mr-96' : ''}`}>
|
||||||
<Outlet />
|
<Outlet />
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user