Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 32 additions & 8 deletions components/auth-form.tsx
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -14,6 +17,8 @@ export function AuthForm({
children: React.ReactNode;
defaultEmail?: string;
}) {
const [showPassword, setShowPassword] = useState(false);

return (
<Form action={action} className="flex flex-col gap-4 px-4 sm:px-16">
<div className="flex flex-col gap-2">
Expand All @@ -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
Expand All @@ -45,13 +50,32 @@ export function AuthForm({
密码
</Label>

<Input
id="password"
name="password"
className="bg-muted text-md md:text-sm"
type="password"
required
/>
<div className="relative">
<Input
id="password"
name="password"
className="bg-muted text-md md:text-sm pr-10"
placeholder="请输入密码"
type={showPassword ? 'text' : 'password'}
required
/>
<Button
type="button"
variant="ghost"
size="sm"
className="absolute right-0 top-0 h-full px-3 py-2 hover:bg-transparent"
onClick={() => setShowPassword(!showPassword)}
>
{showPassword ? (
<EyeOff className="size-4 text-muted-foreground" />
) : (
<Eye className="size-4 text-muted-foreground" />
)}
<span className="sr-only">
{showPassword ? '隐藏密码' : '显示密码'}
</span>
</Button>
</div>
</div>

{children}
Expand Down
61 changes: 48 additions & 13 deletions components/chat-header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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();

Expand Down Expand Up @@ -70,18 +85,38 @@ function PureChatHeader({
/>
)}

{/* <Button
className="bg-zinc-900 dark:bg-zinc-100 hover:bg-zinc-800 dark:hover:bg-zinc-200 text-zinc-50 dark:text-zinc-900 hidden md:flex py-1.5 px-2 h-fit md:h-[34px] order-4 md:ml-auto"
asChild
>
<Link
href={`https://vercel.com/new/clone?repository-url=https://github.com/vercel/ai-chatbot&env=AUTH_SECRET&envDescription=Learn more about how to get the API Keys for the application&envLink=https://github.com/vercel/ai-chatbot/blob/main/.env.example&demo-title=AI Chatbot&demo-description=An Open-Source AI Chatbot Template Built With Next.js and the AI SDK by Vercel.&demo-url=https://chat.vercel.ai&products=[{"type":"integration","protocol":"ai","productSlug":"grok","integrationSlug":"xai"},{"type":"integration","protocol":"storage","productSlug":"neon","integrationSlug":"neon"},{"type":"integration","protocol":"storage","productSlug":"upstash-kv","integrationSlug":"upstash"},{"type":"blob"}]`}
target="_noblank"
>
<VercelIcon size={16} />
Deploy with Vercel
</Link>
</Button> */}
<div className="order-3 md:order-4">
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline" size="icon" className="size-[34px]">
{mounted ? (
<>
{theme === 'light' && <Sun />}
{theme === 'dark' && <Moon />}
{theme === 'system' && <Laptop />}
</>
) : (
// 在客户端挂载前显示一个占位图标
<Loader />
)}
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem onClick={() => setTheme('light')}>
<Sun className="mr-2 size-4" />
<span>浅色主题</span>
</DropdownMenuItem>
<DropdownMenuItem onClick={() => setTheme('dark')}>
<Moon className="mr-2 size-4" />
<span>深色主题</span>
</DropdownMenuItem>
<DropdownMenuItem onClick={() => setTheme('system')}>
<Laptop className="mr-2 size-4" />
<span>跟随系统</span>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</div>
</header>
);
}
Expand Down
4 changes: 2 additions & 2 deletions components/sidebar-toggle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { Button } from './ui/button';
export function SidebarToggle({
className,
}: ComponentProps<typeof SidebarTrigger>) {
const { toggleSidebar } = useSidebar();
const { toggleSidebar, open } = useSidebar();

return (
<Tooltip>
Expand All @@ -27,7 +27,7 @@ export function SidebarToggle({
<SidebarLeftIcon size={16} />
</Button>
</TooltipTrigger>
<TooltipContent align="start">切换侧边栏</TooltipContent>
<TooltipContent align="start">{open ? '收起' : '展开'}</TooltipContent>
</Tooltip>
);
}
9 changes: 2 additions & 7 deletions components/sidebar-user-nav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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 ?? '');

Expand Down Expand Up @@ -60,7 +58,7 @@ export function SidebarUserNav({ user }: { user: User }) {
className="rounded-full"
/>
<span data-testid="user-email" className="truncate">
{isGuest ? '访客' : user?.email}
{isGuest ? '访客' : user?.email?.split('@')[0]}
</span>
<ChevronUp className="ml-auto" />
</SidebarMenuButton>
Expand All @@ -74,11 +72,8 @@ export function SidebarUserNav({ user }: { user: User }) {
<DropdownMenuItem
data-testid="user-nav-item-theme"
className="cursor-pointer"
onSelect={() =>
setTheme(resolvedTheme === 'dark' ? 'light' : 'dark')
}
>
{`切换到${resolvedTheme === 'light' ? '深色' : '浅色'}模式`}
设置
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem asChild data-testid="user-nav-item-auth">
Expand Down
5 changes: 5 additions & 0 deletions next.config.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { NextConfig } from 'next';
import { codeInspectorPlugin } from 'code-inspector-plugin';

const nextConfig: NextConfig = {
experimental: {
Expand All @@ -11,6 +12,10 @@ const nextConfig: NextConfig = {
},
],
},
webpack: (config, { dev, isServer }) => {
config.plugins.push(codeInspectorPlugin({ bundler: 'webpack' }));
return config;
},
};

export default nextConfig;
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down
Loading