From bcbc734b9d28230c3386acaa32700a923a4f0b01 Mon Sep 17 00:00:00 2001 From: lansen Date: Sat, 28 Jun 2025 18:36:30 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=20codeInspectorPlugi?= =?UTF-8?q?n=20&=20=E4=B8=BB=E9=A2=98=E5=88=87=E6=8D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/auth-form.tsx | 40 +++++++-- components/chat-header.tsx | 61 ++++++++++--- components/sidebar-toggle.tsx | 4 +- components/sidebar-user-nav.tsx | 9 +- next.config.ts | 5 ++ package.json | 3 +- pnpm-lock.yaml | 149 ++++++++++++++++++++++++++++++++ 7 files changed, 240 insertions(+), 31 deletions(-) diff --git a/components/auth-form.tsx b/components/auth-form.tsx index 6278ac6..f93603c 100644 --- a/components/auth-form.tsx +++ b/components/auth-form.tsx @@ -1,7 +1,10 @@ import Form from 'next/form'; +import { useState } from 'react'; +import { Eye, EyeOff } from 'lucide-react'; import { Input } from './ui/input'; import { Label } from './ui/label'; +import { Button } from './ui/button'; export function AuthForm({ action, @@ -14,6 +17,8 @@ export function AuthForm({ children: React.ReactNode; defaultEmail?: string; }) { + const [showPassword, setShowPassword] = useState(false); + return (
@@ -29,7 +34,7 @@ export function AuthForm({ name="email" className="bg-muted text-md md:text-sm" type="email" - placeholder="user@acme.com" + placeholder="xxxx@example.com" autoComplete="email" required autoFocus @@ -45,13 +50,32 @@ export function AuthForm({ 密码 - +
+ + +
{children} diff --git a/components/chat-header.tsx b/components/chat-header.tsx index 86ea22e..4a13d8f 100644 --- a/components/chat-header.tsx +++ b/components/chat-header.tsx @@ -2,16 +2,24 @@ import { useRouter } from 'next/navigation'; import { useWindowSize } from 'usehooks-ts'; +import { useTheme } from 'next-themes'; +import { Laptop, Moon, Sun, Loader } from 'lucide-react'; import { ModelSelector } from '@/components/model-selector'; import { SidebarToggle } from '@/components/sidebar-toggle'; import { Button } from '@/components/ui/button'; import type { Session } from 'next-auth'; -import { memo } from 'react'; +import { memo, useEffect, useState } from 'react'; import { PlusIcon } from './icons'; import { useSidebar } from './ui/sidebar'; import { Tooltip, TooltipContent, TooltipTrigger } from './ui/tooltip'; import { type VisibilityType, VisibilitySelector } from './visibility-selector'; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, +} from './ui/dropdown-menu'; function PureChatHeader({ chatId, @@ -28,6 +36,13 @@ function PureChatHeader({ }) { const router = useRouter(); const { open } = useSidebar(); + const { setTheme, theme } = useTheme(); + const [mounted, setMounted] = useState(false); + + // 确保组件只在客户端挂载后渲染主题相关内容 + useEffect(() => { + setMounted(true); + }, []); const { width: windowWidth } = useWindowSize(); @@ -70,18 +85,38 @@ function PureChatHeader({ /> )} - {/* */} +
+ + + + + + setTheme('light')}> + + 浅色主题 + + setTheme('dark')}> + + 深色主题 + + setTheme('system')}> + + 跟随系统 + + + +
); } diff --git a/components/sidebar-toggle.tsx b/components/sidebar-toggle.tsx index 0a56cd2..d161d4c 100644 --- a/components/sidebar-toggle.tsx +++ b/components/sidebar-toggle.tsx @@ -13,7 +13,7 @@ import { Button } from './ui/button'; export function SidebarToggle({ className, }: ComponentProps) { - const { toggleSidebar } = useSidebar(); + const { toggleSidebar, open } = useSidebar(); return ( @@ -27,7 +27,7 @@ export function SidebarToggle({ - 切换侧边栏 + {open ? '收起' : '展开'} ); } diff --git a/components/sidebar-user-nav.tsx b/components/sidebar-user-nav.tsx index 07d3aa9..0e83a8a 100644 --- a/components/sidebar-user-nav.tsx +++ b/components/sidebar-user-nav.tsx @@ -4,7 +4,6 @@ import { ChevronUp } from 'lucide-react'; import Image from 'next/image'; import type { User } from 'next-auth'; import { signOut, useSession } from 'next-auth/react'; -import { useTheme } from 'next-themes'; import { DropdownMenu, @@ -26,7 +25,6 @@ import { guestRegex } from '@/lib/constants'; export function SidebarUserNav({ user }: { user: User }) { const router = useRouter(); const { data, status } = useSession(); - const { setTheme, resolvedTheme } = useTheme(); const isGuest = guestRegex.test(data?.user?.email ?? ''); @@ -60,7 +58,7 @@ export function SidebarUserNav({ user }: { user: User }) { className="rounded-full" /> - {isGuest ? '访客' : user?.email} + {isGuest ? '访客' : user?.email?.split('@')[0]} @@ -74,11 +72,8 @@ export function SidebarUserNav({ user }: { user: User }) { - setTheme(resolvedTheme === 'dark' ? 'light' : 'dark') - } > - {`切换到${resolvedTheme === 'light' ? '深色' : '浅色'}模式`} + 设置 diff --git a/next.config.ts b/next.config.ts index 4415746..f746f86 100644 --- a/next.config.ts +++ b/next.config.ts @@ -1,4 +1,5 @@ import type { NextConfig } from 'next'; +import { codeInspectorPlugin } from 'code-inspector-plugin'; const nextConfig: NextConfig = { experimental: { @@ -11,6 +12,10 @@ const nextConfig: NextConfig = { }, ], }, + webpack: (config, { dev, isServer }) => { + config.plugins.push(codeInspectorPlugin({ bundler: 'webpack' })); + return config; + }, }; export default nextConfig; diff --git a/package.json b/package.json index cdb26c9..2b428ea 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "version": "3.0.23", "private": true, "scripts": { - "dev": "next dev --turbo", + "dev": "next dev", "build": "next build", "start": "next start", "lint": "next lint && biome lint --write --unsafe", @@ -100,6 +100,7 @@ "@types/pdf-parse": "^1.1.4", "@types/react": "^18", "@types/react-dom": "^18", + "code-inspector-plugin": "^0.20.13", "drizzle-kit": "^0.25.0", "eslint": "^8.57.0", "eslint-config-next": "14.2.5", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 51e9113..aa1a92e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -246,6 +246,9 @@ importers: '@types/react-dom': specifier: ^18 version: 18.3.5(@types/react@18.3.18) + code-inspector-plugin: + specifier: ^0.20.13 + version: 0.20.13 drizzle-kit: specifier: ^0.25.0 version: 0.25.0 @@ -353,6 +356,23 @@ packages: nodemailer: optional: true + '@babel/helper-string-parser@7.27.1': + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.27.1': + resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.27.7': + resolution: {integrity: sha512-qnzXzDXdr/po3bOTbTIQZ7+TxNKxpkN5IifVLXS+r7qwynkZfPyjZfE7hCXbo7IoO9TNcSyibgONsf2HauUd3Q==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/types@7.27.7': + resolution: {integrity: sha512-8OLQgDScAOHXnAz2cV+RfzzNMipuLVBz2biuAJFMV9bfkNf393je3VM8CLkjQodW5+iWsSJdSgSWT6rsZoXHPw==} + engines: {node: '>=6.9.0'} + '@biomejs/biome@1.9.4': resolution: {integrity: sha512-1rkd7G70+o9KkTn5KLmDYXihGoTaIGO9PIIN2ZB7UJxFrWw04CZHPYiMRjYsaDvVV7hP1dYNRLxSANLaBFGpog==} engines: {node: '>=14.21.3'} @@ -1799,6 +1819,15 @@ packages: vue-router: optional: true + '@vue/compiler-core@3.5.17': + resolution: {integrity: sha512-Xe+AittLbAyV0pabcN7cP7/BenRBNcteM4aSDCtRvGw0d9OL+HG1u/XHLY/kt1q4fyMeZYXyIYrsHuPSiDPosA==} + + '@vue/compiler-dom@3.5.17': + resolution: {integrity: sha512-+2UgfLKoaNLhgfhV5Ihnk6wB4ljyW1/7wUIog2puUqajiC29Lp5R/IKDdkebh9jTbTogTbsgB+OY9cEWzG95JQ==} + + '@vue/shared@3.5.17': + resolution: {integrity: sha512-CabR+UN630VnsJO/jHWYBC1YVXyMq94KKp6iF5MQgZJs5I8cmjw6oVMO1oDbtBkENSHSSn/UadWlW/OAgdmKrg==} + acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: @@ -1905,6 +1934,9 @@ packages: async-retry@1.3.3: resolution: {integrity: sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==} + async@3.2.6: + resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} + available-typed-arrays@1.0.7: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} @@ -1982,6 +2014,10 @@ packages: ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + chalk@4.1.1: + resolution: {integrity: sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==} + engines: {node: '>=10'} + chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} @@ -2023,6 +2059,12 @@ packages: resolution: {integrity: sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==} engines: {node: '>=0.10.0'} + code-inspector-core@0.20.13: + resolution: {integrity: sha512-cRzU983MM6FsxbmK3i8jDv5HbONWdi81bvSLCdaLGxdwR4+VHHtGS6mBg5txn+V8cR6GQ94HobK35KDj7fZrmg==} + + code-inspector-plugin@0.20.13: + resolution: {integrity: sha512-q9T1hKh1ENGxCG1iKzpsPWnhdafxADOqFvQ5i8gqX8jutu/aEdKtHg1whRePpsuGqgbpYlb5WhZjRWct/ALEzA==} + codemirror@6.0.1: resolution: {integrity: sha512-J8j+nZ+CdWmIeFIGXEFbFPtpiYacFMDR8GlHK3IyHQJMCaVRfGx9NT+Hxivv1ckLWPvNdZqndbr/7lVhrf/Svg==} @@ -2303,6 +2345,9 @@ packages: resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} engines: {node: '>= 0.4'} + esbuild-code-inspector-plugin@0.20.13: + resolution: {integrity: sha512-vtO+/dAc4xc/H0jjM7S6CeFkEQPzHQfPBKEeTSl/frZzFgaPeO0SSXgvrgAKZZ+AZ2tMfZjaQTY5kMSl+crD2Q==} + esbuild-register@3.6.0: resolution: {integrity: sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg==} peerDependencies: @@ -2450,6 +2495,9 @@ packages: estree-util-is-identifier-name@3.0.0: resolution: {integrity: sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==} + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + esutils@2.0.3: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} @@ -2874,6 +2922,9 @@ packages: resolution: {integrity: sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==} engines: {node: '>=0.10'} + launch-ide@1.0.7: + resolution: {integrity: sha512-wJMTq6U2sVYqxrlp544KQxtl8cHoXFfQa2ivDtKJ6ock2ARneiEHqUFce/NQsnNP1aZNg4OXB6g00oFRvni1/Q==} + levn@0.4.1: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} @@ -3313,6 +3364,10 @@ packages: engines: {node: '>=18'} hasBin: true + portfinder@1.0.37: + resolution: {integrity: sha512-yuGIEjDAYnnOex9ddMnKZEMFE0CcGo6zbfzDklkmT1m5z734ss6JMzN9rNB3+RR7iS+F10D4/BVIaXOyh8PQKw==} + engines: {node: '>= 10.12'} + possible-typed-array-names@1.1.0: resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} engines: {node: '>= 0.4'} @@ -3962,9 +4017,15 @@ packages: vfile@6.0.3: resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + vite-code-inspector-plugin@0.20.13: + resolution: {integrity: sha512-CxMjfqJ9vbYRGBHKIx5Ju9xsvsCwTrx/OEbzeqHkFiyvJQhqsYURv48quD00hVLnKUO5T7K3ejhxhtAOG6rCzg==} + w3c-keyname@2.2.8: resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==} + webpack-code-inspector-plugin@0.20.13: + resolution: {integrity: sha512-S9O2NfCCfX+yhuoATbKayZnwDvSI505G4sLHsSORoDsO8gnSzpNBB15WRhmRIp395t4CfIpn583UpnvycisGRw==} + which-boxed-primitive@1.1.1: resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} engines: {node: '>= 0.4'} @@ -4108,6 +4169,19 @@ snapshots: preact: 10.11.3 preact-render-to-string: 5.2.3(preact@10.11.3) + '@babel/helper-string-parser@7.27.1': {} + + '@babel/helper-validator-identifier@7.27.1': {} + + '@babel/parser@7.27.7': + dependencies: + '@babel/types': 7.27.7 + + '@babel/types@7.27.7': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.27.1 + '@biomejs/biome@1.9.4': optionalDependencies: '@biomejs/cli-darwin-arm64': 1.9.4 @@ -5251,6 +5325,21 @@ snapshots: next: 15.3.0-canary.31(@opentelemetry/api@1.9.0)(@playwright/test@1.51.0)(react-dom@19.0.0-rc-45804af1-20241021(react@19.0.0-rc-45804af1-20241021))(react@19.0.0-rc-45804af1-20241021) react: 19.0.0-rc-45804af1-20241021 + '@vue/compiler-core@3.5.17': + dependencies: + '@babel/parser': 7.27.7 + '@vue/shared': 3.5.17 + entities: 4.5.0 + estree-walker: 2.0.2 + source-map-js: 1.2.1 + + '@vue/compiler-dom@3.5.17': + dependencies: + '@vue/compiler-core': 3.5.17 + '@vue/shared': 3.5.17 + + '@vue/shared@3.5.17': {} + acorn-jsx@5.3.2(acorn@8.14.1): dependencies: acorn: 8.14.1 @@ -5378,6 +5467,8 @@ snapshots: dependencies: retry: 0.13.1 + async@3.2.6: {} + available-typed-arrays@1.0.7: dependencies: possible-typed-array-names: 1.1.0 @@ -5444,6 +5535,11 @@ snapshots: ccount@2.0.1: {} + chalk@4.1.1: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + chalk@4.1.2: dependencies: ansi-styles: 4.3.0 @@ -5483,6 +5579,27 @@ snapshots: cluster-key-slot@1.1.2: {} + code-inspector-core@0.20.13: + dependencies: + '@vue/compiler-dom': 3.5.17 + chalk: 4.1.2 + dotenv: 16.4.7 + launch-ide: 1.0.7 + portfinder: 1.0.37 + transitivePeerDependencies: + - supports-color + + code-inspector-plugin@0.20.13: + dependencies: + chalk: 4.1.1 + code-inspector-core: 0.20.13 + dotenv: 16.4.7 + esbuild-code-inspector-plugin: 0.20.13 + vite-code-inspector-plugin: 0.20.13 + webpack-code-inspector-plugin: 0.20.13 + transitivePeerDependencies: + - supports-color + codemirror@6.0.1: dependencies: '@codemirror/autocomplete': 6.18.6 @@ -5746,6 +5863,12 @@ snapshots: is-date-object: 1.1.0 is-symbol: 1.1.1 + esbuild-code-inspector-plugin@0.20.13: + dependencies: + code-inspector-core: 0.20.13 + transitivePeerDependencies: + - supports-color + esbuild-register@3.6.0(esbuild@0.19.12): dependencies: debug: 4.4.0 @@ -6041,6 +6164,8 @@ snapshots: estree-util-is-identifier-name@3.0.0: {} + estree-walker@2.0.2: {} + esutils@2.0.3: {} extend@3.0.2: {} @@ -6496,6 +6621,11 @@ snapshots: dependencies: language-subtag-registry: 0.3.23 + launch-ide@1.0.7: + dependencies: + chalk: 4.1.2 + dotenv: 16.4.7 + levn@0.4.1: dependencies: prelude-ls: 1.2.1 @@ -7122,6 +7252,13 @@ snapshots: optionalDependencies: fsevents: 2.3.2 + portfinder@1.0.37: + dependencies: + async: 3.2.6 + debug: 4.4.0 + transitivePeerDependencies: + - supports-color + possible-typed-array-names@1.1.0: {} postcss-import@15.1.0(postcss@8.5.3): @@ -7937,8 +8074,20 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.2 + vite-code-inspector-plugin@0.20.13: + dependencies: + code-inspector-core: 0.20.13 + transitivePeerDependencies: + - supports-color + w3c-keyname@2.2.8: {} + webpack-code-inspector-plugin@0.20.13: + dependencies: + code-inspector-core: 0.20.13 + transitivePeerDependencies: + - supports-color + which-boxed-primitive@1.1.1: dependencies: is-bigint: 1.1.0