diff --git a/src/app/chat/[id]/page.tsx b/src/app/chat/[id]/page.tsx new file mode 100644 index 0000000..459a93d --- /dev/null +++ b/src/app/chat/[id]/page.tsx @@ -0,0 +1,151 @@ +'use client'; + +import { useState, useRef, useEffect } from 'react'; +import { useParams } from 'next/navigation'; +import { Share2, MoreHorizontal } from 'lucide-react'; +import { Sidebar, SidebarToggle } from '@/components/layout/Sidebar'; +import { ChatInput } from '@/components/features/ChatInput'; +import { MessageBubble } from '@/components/features/MessageBubble'; +import { cn } from '@/lib/utils'; +import { + models, + tools as initialTools, + chatHistories, + sampleMessages, + currentUser +} from '@/data/mock'; +import type { Model, Tool, Message } from '@/types'; + +export default function ChatPage() { + const params = useParams(); + const chatId = params.id as string; + + const [sidebarOpen, setSidebarOpen] = useState(true); + const [selectedModel, setSelectedModel] = useState(models[1]); + const [tools, setTools] = useState(initialTools); + const [messages, setMessages] = useState(sampleMessages); + const messagesEndRef = useRef(null); + + // 获取当前聊天信息 + const currentChat = chatHistories.find(c => c.id === chatId); + const chatTitle = currentChat?.title || '新对话'; + + // 滚动到底部 + const scrollToBottom = () => { + messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' }); + }; + + useEffect(() => { + scrollToBottom(); + }, [messages]); + + const handleToolToggle = (toolId: string) => { + setTools((prev) => + prev.map((tool) => + tool.id === toolId ? { ...tool, enabled: !tool.enabled } : tool + ) + ); + }; + + const handleEnableAllTools = (enabled: boolean) => { + setTools((prev) => + prev.map((tool) => ({ ...tool, enabled })) + ); + }; + + const handleSend = (message: string) => { + // 添加用户消息 + const userMessage: Message = { + id: `msg-${Date.now()}`, + role: 'user', + content: message, + timestamp: new Date(), + }; + setMessages((prev) => [...prev, userMessage]); + + // 模拟 AI 回复 + setTimeout(() => { + const aiMessage: Message = { + id: `msg-${Date.now() + 1}`, + role: 'assistant', + content: '感谢您的消息!这是一个模拟的 AI 回复。在实际应用中,这里会调用 AI API 生成真实的回复内容。\n\n您可以继续与我对话,我会尽力帮助您解决问题。', + timestamp: new Date(), + }; + setMessages((prev) => [...prev, aiMessage]); + }, 1000); + }; + + return ( +
+ {/* 侧边栏 */} + setSidebarOpen(!sidebarOpen)} + /> + + {/* 主内容区 */} +
+ {/* 固定顶部 Header */} +
+
+ setSidebarOpen(!sidebarOpen)} /> +

+ {chatTitle} +

+
+
+ + +
+
+ + {/* 消息列表区域 */} +
+
+ {messages.map((message) => ( + + ))} +
+
+
+ + {/* 固定底部输入框 */} +
+
+ +
+
+
+
+ ); +} diff --git a/src/app/settings/page.tsx b/src/app/settings/page.tsx new file mode 100644 index 0000000..350aa6d --- /dev/null +++ b/src/app/settings/page.tsx @@ -0,0 +1,317 @@ +'use client'; + +import { useState } from 'react'; +import Link from 'next/link'; +import { ArrowLeft, Zap, Download } from 'lucide-react'; +import { Sidebar, SidebarToggle } from '@/components/layout/Sidebar'; +import { Toggle } from '@/components/ui/Toggle'; +import { cn } from '@/lib/utils'; +import { currentUser, chatHistories, models } from '@/data/mock'; +import type { Settings } from '@/types'; + +export default function SettingsPage() { + const [sidebarOpen, setSidebarOpen] = useState(true); + const [settings, setSettings] = useState({ + defaultModel: 'sonnet', + theme: 'light', + language: 'zh-CN', + enableWebSearch: true, + enableCodeExecution: false, + saveChatHistory: true, + }); + + const handleToggle = (key: keyof Settings) => { + setSettings((prev) => ({ + ...prev, + [key]: !prev[key], + })); + }; + + const handleSelectChange = (key: keyof Settings, value: string) => { + setSettings((prev) => ({ + ...prev, + [key]: value, + })); + }; + + return ( +
+ {/* 侧边栏 */} + setSidebarOpen(!sidebarOpen)} + /> + + {/* 主内容区 */} +
+ {/* Header */} +
+ setSidebarOpen(!sidebarOpen)} /> +
+ + {/* Body */} +
+
+ {/* 返回链接 */} + + + 返回聊天 + + + {/* 页面标题 */} +
+

+ 设置 +

+

+ 管理您的账户设置和偏好 +

+
+ + {/* 账户设置 */} + + + + + + + + {currentUser.plan === 'free' ? '免费计划' : '专业计划'} + + } + > + + + + +
+
+
+
+
+
+ 35 / 100 条消息 + 35% +
+
+
+ + + + {/* 偏好设置 */} + + + + + + + + + + + + + + + handleToggle('enableWebSearch')} + /> + + + + handleToggle('enableCodeExecution')} + /> + + + + {/* 数据与隐私 */} + + + handleToggle('saveChatHistory')} + /> + + + + + + + + + + + + {/* 危险区域 */} + + + + + +
+
+
+
+ ); +} + +// 设置区域组件 +interface SettingsSectionProps { + title: string; + description: string; + children: React.ReactNode; + variant?: 'default' | 'danger'; +} + +function SettingsSection({ title, description, children, variant = 'default' }: SettingsSectionProps) { + return ( +
+
+

+ {title} +

+

+ {description} +

+
+
{children}
+
+ ); +} + +// 设置项组件 +interface SettingsItemProps { + label: string; + description: React.ReactNode; + children: React.ReactNode; +} + +function SettingsItem({ label, description, children }: SettingsItemProps) { + return ( +
+
+
+ {label} +
+
+ {description} +
+
+
{children}
+
+ ); +}