From 08de9e0cabfeae695e290c3ef1f468199d4ccd66 Mon Sep 17 00:00:00 2001 From: Li Xin Date: Mon, 28 Apr 2025 10:07:36 +0800 Subject: [PATCH] feat: implement basic layout of landing page --- src/server/app.py | 1 - web/package.json | 1 + web/pnpm-lock.yaml | 12 + web/public/images/deer-hero.svg | 6 + web/src/app/_components/logo.tsx | 13 +- web/src/app/_components/theme-toggle.tsx | 2 + web/src/app/chat/main.tsx | 9 - web/src/app/chat/page.tsx | 6 +- web/src/app/layout.tsx | 2 +- web/src/app/page.tsx | 354 +++++++++++++++++- web/src/components/magicui/aurora-text.tsx | 43 +++ web/src/components/magicui/bento-grid.tsx | 83 ++++ .../components/magicui/flickering-grid.tsx | 199 ++++++++++ web/src/styles/globals.css | 36 +- 14 files changed, 737 insertions(+), 30 deletions(-) create mode 100644 web/public/images/deer-hero.svg create mode 100644 web/src/components/magicui/aurora-text.tsx create mode 100644 web/src/components/magicui/bento-grid.tsx create mode 100644 web/src/components/magicui/flickering-grid.tsx diff --git a/src/server/app.py b/src/server/app.py index ea2156a..c910dac 100644 --- a/src/server/app.py +++ b/src/server/app.py @@ -13,7 +13,6 @@ from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import Response, StreamingResponse from langchain_core.messages import AIMessageChunk, ToolMessage from langgraph.types import Command -from mcp import ClientSession from src.graph.builder import build_graph_with_memory from src.podcast.graph.builder import build_graph as build_podcast_graph diff --git a/web/package.json b/web/package.json index 1364054..4a9fb99 100644 --- a/web/package.json +++ b/web/package.json @@ -24,6 +24,7 @@ "@radix-ui/react-collapsible": "^1.1.8", "@radix-ui/react-dialog": "^1.1.10", "@radix-ui/react-dropdown-menu": "^2.1.11", + "@radix-ui/react-icons": "^1.3.2", "@radix-ui/react-label": "^2.1.4", "@radix-ui/react-scroll-area": "^1.2.4", "@radix-ui/react-select": "^2.2.2", diff --git a/web/pnpm-lock.yaml b/web/pnpm-lock.yaml index 9a6c167..8e530e9 100644 --- a/web/pnpm-lock.yaml +++ b/web/pnpm-lock.yaml @@ -29,6 +29,9 @@ importers: '@radix-ui/react-dropdown-menu': specifier: ^2.1.11 version: 2.1.11(@types/react-dom@19.1.1(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-icons': + specifier: ^1.3.2 + version: 1.3.2(react@19.1.0) '@radix-ui/react-label': specifier: ^2.1.4 version: 2.1.4(@types/react-dom@19.1.1(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) @@ -721,6 +724,11 @@ packages: '@types/react-dom': optional: true + '@radix-ui/react-icons@1.3.2': + resolution: {integrity: sha512-fyQIhGDhzfc9pK2kH6Pl9c4BDJGfMkPqkyIgYDthyNYoNg3wVhoJMMh19WS4Up/1KMPFVpNsT2q3WmXn2N1m6g==} + peerDependencies: + react: ^16.x || ^17.x || ^18.x || ^19.0.0 || ^19.0.0-rc + '@radix-ui/react-id@1.1.1': resolution: {integrity: sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==} peerDependencies: @@ -3932,6 +3940,10 @@ snapshots: '@types/react': 19.1.2 '@types/react-dom': 19.1.1(@types/react@19.1.2) + '@radix-ui/react-icons@1.3.2(react@19.1.0)': + dependencies: + react: 19.1.0 + '@radix-ui/react-id@1.1.1(@types/react@19.1.2)(react@19.1.0)': dependencies: '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.2)(react@19.1.0) diff --git a/web/public/images/deer-hero.svg b/web/public/images/deer-hero.svg new file mode 100644 index 0000000..9bbfb29 --- /dev/null +++ b/web/public/images/deer-hero.svg @@ -0,0 +1,6 @@ + + + + diff --git a/web/src/app/_components/logo.tsx b/web/src/app/_components/logo.tsx index c92e374..64ea540 100644 --- a/web/src/app/_components/logo.tsx +++ b/web/src/app/_components/logo.tsx @@ -1,25 +1,14 @@ // Copyright (c) 2025 Bytedance Ltd. and/or its affiliates // SPDX-License-Identifier: MIT -import { useState } from "react"; - -import { Markdown } from "./markdown"; - export function Logo() { - const [text, setText] = useState("🦌 DeerFlow"); return ( - setText( - "🦌 **D**eep **E**xploration and **E**fficient **R**esearch Flow", - ) - } - onMouseLeave={() => setText("🦌 DeerFlow")} > - {text} + 🦌 DeerFlow ); } diff --git a/web/src/app/_components/theme-toggle.tsx b/web/src/app/_components/theme-toggle.tsx index ca30ac6..2ae1ab1 100644 --- a/web/src/app/_components/theme-toggle.tsx +++ b/web/src/app/_components/theme-toggle.tsx @@ -1,6 +1,8 @@ // Copyright (c) 2025 Bytedance Ltd. and/or its affiliates // SPDX-License-Identifier: MIT +"use client"; + import { Monitor, Moon, Sun } from "lucide-react"; import { useTheme } from "next-themes"; diff --git a/web/src/app/chat/main.tsx b/web/src/app/chat/main.tsx index 3d41653..9da46f4 100644 --- a/web/src/app/chat/main.tsx +++ b/web/src/app/chat/main.tsx @@ -3,24 +3,15 @@ "use client"; -import { GithubOutlined } from "@ant-design/icons"; -import Link from "next/link"; import { useMemo } from "react"; -import { Button } from "~/components/ui/button"; -import { useReplay } from "~/core/replay"; import { useStore } from "~/core/store"; import { cn } from "~/lib/utils"; -import { Logo } from "../_components/logo"; import { MessagesBlock } from "../_components/messages-block"; import { ResearchBlock } from "../_components/research-block"; -import { ThemeToggle } from "../_components/theme-toggle"; -import { Tooltip } from "../_components/tooltip"; -import { SettingsDialog } from "../_settings/dialogs/settings-dialog"; export default function Main() { - const { isReplay } = useReplay(); const openResearchId = useStore((state) => state.openResearchId); const doubleColumnMode = useMemo( () => openResearchId !== null, diff --git a/web/src/app/chat/page.tsx b/web/src/app/chat/page.tsx index 26dba29..f674fbe 100644 --- a/web/src/app/chat/page.tsx +++ b/web/src/app/chat/page.tsx @@ -25,9 +25,7 @@ export default function HomePage() {
- - {!isReplay && } - + + + {!isReplay && }
Loading DeerFlow...}> diff --git a/web/src/app/layout.tsx b/web/src/app/layout.tsx index ae6be49..6ff3163 100644 --- a/web/src/app/layout.tsx +++ b/web/src/app/layout.tsx @@ -26,7 +26,7 @@ export default function RootLayout({ }: Readonly<{ children: React.ReactNode }>) { return ( - + +
+
+ + + + +
+