'use client' import { useEffect, useMemo, useState } from 'react' import { useContext } from 'use-context-selector' import { useTranslation } from 'react-i18next' import { RiCloseLine, RiListUnordered } from '@remixicon/react' import TemplateEn from './template/template.en.mdx' import TemplateZh from './template/template.zh.mdx' import TemplateJa from './template/template.ja.mdx' import TemplateAdvancedChatEn from './template/template_advanced_chat.en.mdx' import TemplateAdvancedChatZh from './template/template_advanced_chat.zh.mdx' import TemplateAdvancedChatJa from './template/template_advanced_chat.ja.mdx' import TemplateWorkflowEn from './template/template_workflow.en.mdx' import TemplateWorkflowZh from './template/template_workflow.zh.mdx' import TemplateWorkflowJa from './template/template_workflow.ja.mdx' import TemplateChatEn from './template/template_chat.en.mdx' import TemplateChatZh from './template/template_chat.zh.mdx' import TemplateChatJa from './template/template_chat.ja.mdx' import I18n from '@/context/i18n' import { LanguagesSupported } from '@/i18n-config/language' import useTheme from '@/hooks/use-theme' import { Theme } from '@/types/app' import cn from '@/utils/classnames' type IDocProps = { appDetail: any } const Doc = ({ appDetail }: IDocProps) => { const { locale } = useContext(I18n) const { t } = useTranslation() const [toc, setToc] = useState>([]) const [isTocExpanded, setIsTocExpanded] = useState(false) const [activeSection, setActiveSection] = useState('') const { theme } = useTheme() const variables = appDetail?.model_config?.configs?.prompt_variables || [] const inputs = variables.reduce((res: any, variable: any) => { res[variable.key] = variable.name || '' return res }, {}) useEffect(() => { const mediaQuery = window.matchMedia('(min-width: 1280px)') setIsTocExpanded(mediaQuery.matches) }, []) useEffect(() => { const extractTOC = () => { const article = document.querySelector('article') if (article) { const headings = article.querySelectorAll('h2') const tocItems = Array.from(headings).map((heading) => { const anchor = heading.querySelector('a') if (anchor) { return { href: anchor.getAttribute('href') || '', text: anchor.textContent || '', } } return null }).filter((item): item is { href: string; text: string } => item !== null) setToc(tocItems) if (tocItems.length > 0) setActiveSection(tocItems[0].href.replace('#', '')) } } setTimeout(extractTOC, 0) }, [appDetail, locale]) useEffect(() => { const handleScroll = () => { const scrollContainer = document.querySelector('.overflow-auto') if (!scrollContainer || toc.length === 0) return let currentSection = '' toc.forEach((item) => { const targetId = item.href.replace('#', '') const element = document.getElementById(targetId) if (element) { const rect = element.getBoundingClientRect() if (rect.top <= window.innerHeight / 2) currentSection = targetId } }) if (currentSection && currentSection !== activeSection) setActiveSection(currentSection) } const scrollContainer = document.querySelector('.overflow-auto') if (scrollContainer) { scrollContainer.addEventListener('scroll', handleScroll) handleScroll() return () => scrollContainer.removeEventListener('scroll', handleScroll) } }, [toc, activeSection]) const handleTocClick = (e: React.MouseEvent, item: { href: string; text: string }) => { e.preventDefault() const targetId = item.href.replace('#', '') const element = document.getElementById(targetId) if (element) { const scrollContainer = document.querySelector('.overflow-auto') if (scrollContainer) { const headerOffset = 80 const elementTop = element.offsetTop - headerOffset scrollContainer.scrollTo({ top: elementTop, behavior: 'smooth', }) } } } const Template = useMemo(() => { if (appDetail?.mode === 'chat' || appDetail?.mode === 'agent-chat') { switch (locale) { case LanguagesSupported[1]: return case LanguagesSupported[7]: return default: return } } if (appDetail?.mode === 'advanced-chat') { switch (locale) { case LanguagesSupported[1]: return case LanguagesSupported[7]: return default: return } } if (appDetail?.mode === 'workflow') { switch (locale) { case LanguagesSupported[1]: return case LanguagesSupported[7]: return default: return } } if (appDetail?.mode === 'completion') { switch (locale) { case LanguagesSupported[1]: return case LanguagesSupported[7]: return default: return } } return null }, [appDetail, locale, variables, inputs]) return (
{isTocExpanded ? ( ) : ( )}
{Template}
) } export default Doc