diff --git a/src/App.tsx b/src/App.tsx index f7a293e..6b4b6bf 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,111 +1,12 @@ -import { useState } from 'react' + import { BrowserRouter as Router, Routes, Route, Navigate } from 'react-router-dom' -import CanvasArea from './components/CanvasArea' -import TopBar from './components/TopBar' -import SideBar from './components/SideBar' -import AIChatPanel from './components/AIChatPanel' -import Login from './components/auth/Login' -import Register from './components/auth/Register' -import Projects from './components/auth/Projects' +import Login from './pages/auth/Login' +import Register from './pages/auth/Register' +import Projects from './pages/app/Projects' +import MainApp from './pages/app/MainApp' import './App.css' -// 模拟设计文件数据 -const MOCK_DESIGN_FILES = [ - { - name: 'text_1.html', - path: '/designs/text_1.html', - modified: new Date(), - content: '

Hello World

This is a test design file.

', - fileType: 'html', - relationships: { - parent: undefined, - children: ['text_1_1.html'] - } - }, - { - name: 'text_1_1.html', - path: '/designs/text_1_1.html', - modified: new Date(), - content: '

Hello World - Version 1

This is a modified version.

', - fileType: 'html', - relationships: { - parent: 'text_1.html', - children: ['text_1_1_1.html'] - } - }, - { - name: 'text_1_1_1.html', - path: '/designs/text_1_1_1.html', - modified: new Date(), - content: '

Hello World - Version 1.1

This is another modified version.

', - fileType: 'html', - relationships: { - parent: 'text_1_1.html', - children: [] - } - }, - { - name: 'text_2.html', - path: '/designs/text_2.html', - modified: new Date(), - content: '

Another Design

This is a different design file.

', - fileType: 'html', - relationships: { - parent: undefined, - children: [] - } - } -] -// 主应用组件 -const MainApp: React.FC = () => { - const [isChatVisible, setIsChatVisible] = useState(true) - const [selectedFrames, setSelectedFrames] = useState([]) - const [designFiles, setDesignFiles] = useState(MOCK_DESIGN_FILES) - - const toggleChat = () => { - setIsChatVisible(!isChatVisible) - } - - const handleFrameSelect = (frames: string[]) => { - setSelectedFrames(frames) - } - - const handleSelectNote = (frameName: string, note: string) => { - console.log('添加备注到设计元素:', frameName, note) - } - - const handleCreateContext = (title: string, description: string) => { - console.log('创建上下文:', { title, description }) - const newFrame = { - name: title, - path: `/context/${title}`, - modified: new Date(), - content: description, - fileType: 'html' as const, - size: description.length, - version: '1.0', - generation: 0, - branchIndex: 0, - parentDesign: null, - children: [], - relationships: { - parent: undefined, - children: [] - } - } - setDesignFiles([...designFiles, newFrame]) - } - - return ( -
- - - - {isChatVisible && } -
- ) -} // 路由保护组件 const ProtectedRoute: React.FC<{ children: React.ReactNode }> = ({ children }) => { diff --git a/src/components/SideBar.tsx b/src/components/SideBar.tsx index 97b80d4..b615a56 100644 --- a/src/components/SideBar.tsx +++ b/src/components/SideBar.tsx @@ -1,4 +1,4 @@ -import { useState, useEffect } from 'react' +import { useState } from 'react' import { useTranslation } from 'react-i18next' import './SideBar.css' import { ArrowIcon, NoteIcon, CopyIcon, PaletteIcon, PushPinIcon, PlusIcon } from './Icons' diff --git a/src/components/CanvasArea.tsx b/src/pages/app/CanvasArea.tsx similarity index 98% rename from src/components/CanvasArea.tsx rename to src/pages/app/CanvasArea.tsx index 4d55a6b..b6903e1 100644 --- a/src/components/CanvasArea.tsx +++ b/src/pages/app/CanvasArea.tsx @@ -1,14 +1,14 @@ import { useRef, useEffect, useState, useCallback } from 'react' import { TransformWrapper, TransformComponent, ReactZoomPanPinchRef } from 'react-zoom-pan-pinch' -import DesignFrame from './DesignFrame' -import ConnectionLines from './ConnectionLines' +import DesignFrame from '../../components/DesignFrame' +import ConnectionLines from '../../components/ConnectionLines' import { generateResponsiveConfig, buildHierarchyTree, calculateHierarchyPositions, getHierarchicalPosition, detectDesignRelationships -} from '../utils/gridLayout' +} from '../../utils/gridLayout' import { DesignFile, CanvasConfig, @@ -20,10 +20,8 @@ import { LayoutMode, HierarchyTree, ConnectionLine -} from '../types/canvas.types' +} from '../../types/canvas.types' import { - ZoomInIcon, - ZoomOutIcon, HomeIcon, RefreshIcon, GlobeIcon, @@ -32,9 +30,9 @@ import { DesktopIcon, TreeIcon, LinkIcon -} from './Icons' +} from '../../components/Icons' import { useTranslation } from 'react-i18next' -import './CanvasArea.css' +import '../../components/CanvasArea.css' const CANVAS_CONFIG: CanvasConfig = { frameSize: { width: 320, height: 400 }, @@ -116,7 +114,7 @@ interface CanvasAreaProps { setDesignFiles?: (files: DesignFile[]) => void } -const CanvasArea: React.FC = ({ onFrameSelect, designFiles: externalDesignFiles, setDesignFiles: externalSetDesignFiles }) => { +const CanvasArea: React.FC = ({ onFrameSelect, designFiles: externalDesignFiles }) => { const { t } = useTranslation() const [designFiles, setDesignFiles] = useState([]) const [selectedFrames, setSelectedFrames] = useState([]) @@ -170,7 +168,7 @@ const CanvasArea: React.FC = ({ onFrameSelect, designFiles: ext }, [useGlobalViewport, globalViewportMode, frameViewports]) const handleFrameViewportChange = useCallback((fileName: string, viewport: ViewportMode) => { - setFrameViewports(prev => ({ + setFrameViewports((prev: FrameViewportState) => ({ ...prev, [fileName]: viewport })) @@ -449,7 +447,7 @@ const CanvasArea: React.FC = ({ onFrameSelect, designFiles: ext y: mousePos.y - dragState.offset.y } - setDragState(prev => ({ + setDragState((prev: DragState) => ({ ...prev, currentPosition: newPosition })) @@ -464,7 +462,7 @@ const CanvasArea: React.FC = ({ onFrameSelect, designFiles: ext y: Math.round(dragState.currentPosition.y / gridSize) * gridSize } - setCustomPositions(prev => ({ + setCustomPositions((prev: FramePositionState) => ({ ...prev, [dragState.draggedFrame!]: snappedPosition })) diff --git a/src/pages/app/MainApp.tsx b/src/pages/app/MainApp.tsx new file mode 100644 index 0000000..365a061 --- /dev/null +++ b/src/pages/app/MainApp.tsx @@ -0,0 +1,106 @@ +import { useState } from 'react' +import CanvasArea from './CanvasArea' +import TopBar from '../../components/TopBar' +import SideBar from '../../components/SideBar' +import AIChatPanel from '../../components/AIChatPanel' +import '../../App.css' + +// 模拟设计文件数据 +const MOCK_DESIGN_FILES = [ + { + name: 'text_1.html', + path: '/designs/text_1.html', + modified: new Date(), + content: '

Hello World

This is a test design file.

', + fileType: 'html', + relationships: { + parent: undefined, + children: ['text_1_1.html'] + } + }, + { + name: 'text_1_1.html', + path: '/designs/text_1_1.html', + modified: new Date(), + content: '

Hello World - Version 1

This is a modified version.

', + fileType: 'html', + relationships: { + parent: 'text_1.html', + children: ['text_1_1_1.html'] + } + }, + { + name: 'text_1_1_1.html', + path: '/designs/text_1_1_1.html', + modified: new Date(), + content: '

Hello World - Version 1.1

This is another modified version.

', + fileType: 'html', + relationships: { + parent: 'text_1_1.html', + children: [] + } + }, + { + name: 'text_2.html', + path: '/designs/text_2.html', + modified: new Date(), + content: '

Another Design

This is a different design file.

', + fileType: 'html', + relationships: { + parent: undefined, + children: [] + } + } +] + +// 主应用组件 +const MainApp: React.FC = () => { + const [isChatVisible, setIsChatVisible] = useState(true) + const [selectedFrames, setSelectedFrames] = useState([]) + const [designFiles, setDesignFiles] = useState(MOCK_DESIGN_FILES) + + const toggleChat = () => { + setIsChatVisible(!isChatVisible) + } + + const handleFrameSelect = (frames: string[]) => { + setSelectedFrames(frames) + } + + const handleSelectNote = (frameName: string, note: string) => { + console.log('添加备注到设计元素:', frameName, note) + } + + const handleCreateContext = (title: string, description: string) => { + console.log('创建上下文:', { title, description }) + const newFrame = { + name: title, + path: `/context/${title}`, + modified: new Date(), + content: description, + fileType: 'html' as const, + size: description.length, + version: '1.0', + generation: 0, + branchIndex: 0, + parentDesign: null, + children: [], + relationships: { + parent: undefined, + children: [] + } + } + setDesignFiles([...designFiles, newFrame]) + } + + return ( +
+ + + + {isChatVisible && } +
+ ) +} + +export default MainApp \ No newline at end of file diff --git a/src/components/auth/Projects.tsx b/src/pages/app/Projects.tsx similarity index 87% rename from src/components/auth/Projects.tsx rename to src/pages/app/Projects.tsx index 004cb54..ef8e1d8 100644 --- a/src/components/auth/Projects.tsx +++ b/src/pages/app/Projects.tsx @@ -1,6 +1,6 @@ import React, { useState, useEffect } from 'react'; import { useNavigate } from 'react-router-dom'; -import './Auth.css'; +import '../auth/Auth.css'; interface Project { id: string; @@ -86,6 +86,11 @@ const Projects: React.FC = () => { ); } + const handleProjectClick = (projectId: string) => { + // 跳转到canvas页面,并传递项目ID + navigate(`/app?projectId=${projectId}`); + }; + return (
@@ -99,7 +104,12 @@ const Projects: React.FC = () => {
暂无项目
) : ( projects.map((project) => ( -
+
handleProjectClick(project.id)} + style={{ cursor: 'pointer' }} + >

{project.name}

{project.description}

diff --git a/src/components/auth/Auth.css b/src/pages/auth/Auth.css similarity index 100% rename from src/components/auth/Auth.css rename to src/pages/auth/Auth.css diff --git a/src/components/auth/Login.tsx b/src/pages/auth/Login.tsx similarity index 100% rename from src/components/auth/Login.tsx rename to src/pages/auth/Login.tsx diff --git a/src/components/auth/Register.tsx b/src/pages/auth/Register.tsx similarity index 100% rename from src/components/auth/Register.tsx rename to src/pages/auth/Register.tsx