mirror of
https://github.com/woodchen-ink/Q58Connect.git
synced 2025-07-18 05:51:55 +08:00
refactor: Remove AuthStateSync component and update layout
This commit is contained in:
parent
a2964a177b
commit
aed648fed5
@ -18,12 +18,12 @@ import {
|
||||
TypographyLead,
|
||||
TypographyMuted,
|
||||
} from "@/components/ui/typography";
|
||||
import { NavBar } from "@/components/layout/nav-bar";
|
||||
import { Header } from "@/components/layout/header";
|
||||
|
||||
export default function HomePage() {
|
||||
return (
|
||||
<div className="flex min-h-screen flex-col">
|
||||
<NavBar />
|
||||
<Header />
|
||||
<main className="flex-1">
|
||||
<Section className="pb-0">
|
||||
<Container>
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { redirect } from "next/navigation";
|
||||
|
||||
import { getCurrentUser } from "@/lib/session";
|
||||
import { AuthStateSync } from "@/components/auth/auth-state-sync";
|
||||
|
||||
export default async function AuthLayout({
|
||||
children,
|
||||
@ -17,7 +16,6 @@ export default async function AuthLayout({
|
||||
|
||||
return (
|
||||
<>
|
||||
<AuthStateSync />
|
||||
<div className="min-h-screen">
|
||||
<div className="flex h-screen w-screen flex-col items-center justify-center">
|
||||
{children}
|
||||
|
@ -1,20 +0,0 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect } from "react";
|
||||
import { usePathname, useRouter } from "next/navigation";
|
||||
import { useSession } from "next-auth/react";
|
||||
|
||||
export function AuthStateSync() {
|
||||
const { data: session, status, update } = useSession();
|
||||
const router = useRouter();
|
||||
const pathname = usePathname();
|
||||
|
||||
useEffect(() => {
|
||||
// 当状态从"loading"变为"authenticated"时,强制刷新路由
|
||||
if (status === "authenticated" && session?.user) {
|
||||
router.refresh();
|
||||
}
|
||||
}, [status, session]);
|
||||
|
||||
return null;
|
||||
}
|
191
src/components/layout/header-client.tsx
Normal file
191
src/components/layout/header-client.tsx
Normal file
@ -0,0 +1,191 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useState } from "react";
|
||||
import Link from "next/link";
|
||||
import { usePathname, useRouter } from "next/navigation";
|
||||
import { ChevronDown, User } from "lucide-react";
|
||||
import { signOut } from "next-auth/react";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
} from "@/components/ui/dropdown-menu";
|
||||
|
||||
import { ThemeToggle } from "../theme-toggle";
|
||||
|
||||
interface HeaderClientProps {
|
||||
initialUser: any;
|
||||
}
|
||||
|
||||
export function HeaderClient({ initialUser }: HeaderClientProps) {
|
||||
const [user, setUser] = useState(initialUser);
|
||||
const router = useRouter();
|
||||
const pathname = usePathname();
|
||||
|
||||
const handleSignOut = async () => {
|
||||
await signOut({ redirect: false });
|
||||
setUser(null);
|
||||
router.refresh();
|
||||
router.push("/");
|
||||
};
|
||||
|
||||
const renderNavLinks = () => {
|
||||
if (!user) return null;
|
||||
|
||||
return (
|
||||
<div className="ml-8 flex items-center space-x-1">
|
||||
<Link
|
||||
href="/dashboard"
|
||||
className={cn(
|
||||
"rounded-md px-3 py-2 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground",
|
||||
pathname === "/dashboard"
|
||||
? "bg-accent text-accent-foreground"
|
||||
: "text-muted-foreground",
|
||||
)}
|
||||
>
|
||||
控制台
|
||||
</Link>
|
||||
<Link
|
||||
href="/dashboard/clients"
|
||||
className={cn(
|
||||
"rounded-md px-3 py-2 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground",
|
||||
pathname.startsWith("/dashboard/clients")
|
||||
? "bg-accent text-accent-foreground"
|
||||
: "text-muted-foreground",
|
||||
)}
|
||||
>
|
||||
应用管理
|
||||
</Link>
|
||||
<Link
|
||||
href="/dashboard/settings"
|
||||
className={cn(
|
||||
"rounded-md px-3 py-2 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground",
|
||||
pathname === "/dashboard/settings"
|
||||
? "bg-accent text-accent-foreground"
|
||||
: "text-muted-foreground",
|
||||
)}
|
||||
>
|
||||
设置
|
||||
</Link>
|
||||
{user.role === "ADMIN" && (
|
||||
<>
|
||||
<div className="mx-2 h-4 w-px bg-border" />
|
||||
<Link
|
||||
href="/admin"
|
||||
className={cn(
|
||||
"rounded-md px-3 py-2 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground",
|
||||
pathname === "/admin"
|
||||
? "bg-accent text-accent-foreground"
|
||||
: "text-muted-foreground",
|
||||
)}
|
||||
>
|
||||
管理后台
|
||||
</Link>
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className={cn(
|
||||
"rounded-md px-3 py-2 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground",
|
||||
pathname.startsWith("/admin/") && pathname !== "/admin"
|
||||
? "bg-accent text-accent-foreground"
|
||||
: "text-muted-foreground",
|
||||
)}
|
||||
>
|
||||
管理功能
|
||||
<ChevronDown className="ml-1 h-4 w-4" />
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="start">
|
||||
<DropdownMenuItem asChild>
|
||||
<Link
|
||||
href="/admin/users"
|
||||
className={cn(
|
||||
"w-full",
|
||||
pathname === "/admin/users" && "bg-accent",
|
||||
)}
|
||||
>
|
||||
用户列表
|
||||
</Link>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem asChild>
|
||||
<Link
|
||||
href="/admin/clients"
|
||||
className={cn(
|
||||
"w-full",
|
||||
pathname === "/admin/clients" && "bg-accent",
|
||||
)}
|
||||
>
|
||||
应用管理
|
||||
</Link>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem asChild>
|
||||
<Link
|
||||
href="/admin/authorizations"
|
||||
className={cn(
|
||||
"w-full",
|
||||
pathname === "/admin/authorizations" && "bg-accent",
|
||||
)}
|
||||
>
|
||||
授权管理
|
||||
</Link>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem asChild>
|
||||
<Link
|
||||
href="/admin/logs"
|
||||
className={cn(
|
||||
"w-full",
|
||||
pathname === "/admin/logs" && "bg-accent",
|
||||
)}
|
||||
>
|
||||
系统日志
|
||||
</Link>
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex items-center space-x-4">
|
||||
{renderNavLinks()}
|
||||
<ThemeToggle />
|
||||
{user ? (
|
||||
<div className="flex items-center gap-3">
|
||||
<Avatar className="h-8 w-8">
|
||||
<AvatarImage src={user.avatarUrl || undefined} />
|
||||
<AvatarFallback>
|
||||
{user.name?.charAt(0) || user.username?.charAt(0)}
|
||||
</AvatarFallback>
|
||||
</Avatar>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={handleSignOut}
|
||||
className="text-muted-foreground hover:text-red-600"
|
||||
>
|
||||
退出
|
||||
</Button>
|
||||
</div>
|
||||
) : (
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="border-[#25263A] text-[#25263A] hover:bg-[#25263A] hover:text-white dark:border-[#A0A1B2] dark:text-[#A0A1B2] dark:hover:bg-[#A0A1B2] dark:hover:text-[#25263A]"
|
||||
onClick={() => router.push("/sign-in")}
|
||||
>
|
||||
登录
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
26
src/components/layout/header.tsx
Normal file
26
src/components/layout/header.tsx
Normal file
@ -0,0 +1,26 @@
|
||||
import Link from "next/link";
|
||||
|
||||
import { getCurrentUser } from "@/lib/session";
|
||||
import { HeaderClient } from "@/components/layout/header-client";
|
||||
|
||||
export async function Header() {
|
||||
const user = await getCurrentUser();
|
||||
|
||||
return (
|
||||
<header className="sticky top-0 z-10 bg-white shadow-md dark:bg-gray-800">
|
||||
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
|
||||
<div className="flex h-14 items-center justify-between">
|
||||
<div className="flex items-center">
|
||||
<Link href="/" className="flex items-center space-x-3">
|
||||
<h1 className="text-2xl font-bold text-[#25263A] dark:text-white">
|
||||
Q58 Connect
|
||||
</h1>
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<HeaderClient initialUser={user} />
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user