mirror of
https://github.com/woodchen-ink/Q58Connect.git
synced 2025-07-18 14:01:55 +08:00
refactor: Redesign homepage and header with responsive layout and improved styling
This commit is contained in:
parent
3bbf87d875
commit
ce3baad450
@ -1,5 +1,5 @@
|
|||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { ArrowRight, CheckCircle2 } from "lucide-react";
|
import { ArrowRight, CheckCircle2, Code2, Lock, Users } from "lucide-react";
|
||||||
|
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import {
|
import {
|
||||||
@ -25,20 +25,29 @@ export default function HomePage() {
|
|||||||
<div className="flex min-h-screen flex-col">
|
<div className="flex min-h-screen flex-col">
|
||||||
<Header />
|
<Header />
|
||||||
<main className="flex-1">
|
<main className="flex-1">
|
||||||
<Section className="pb-0">
|
{/* Hero Section */}
|
||||||
|
<Section className="relative overflow-hidden bg-gradient-to-b from-white to-gray-50 pb-16 pt-24 dark:from-gray-900 dark:to-gray-800">
|
||||||
|
<div className="absolute inset-0">
|
||||||
|
<div className="bg-grid-black/[0.02] dark:bg-grid-white/[0.02] absolute inset-0" />
|
||||||
|
</div>
|
||||||
<Container>
|
<Container>
|
||||||
<div className="flex flex-col items-center justify-center space-y-8 text-center">
|
<div className="relative flex flex-col items-center justify-center space-y-8 text-center">
|
||||||
<TypographyH1 className="text-4xl font-bold tracking-tighter sm:text-5xl md:text-6xl lg:text-7xl">
|
<div className="space-y-6">
|
||||||
|
<h1 className="text-4xl font-bold tracking-tighter text-gray-900 dark:text-white sm:text-5xl md:text-6xl lg:text-7xl">
|
||||||
Q58 Connect
|
Q58 Connect
|
||||||
</TypographyH1>
|
</h1>
|
||||||
<TypographyLead className="max-w-[600px]">
|
<div className="mx-auto max-w-[800px] px-4">
|
||||||
使用 Q58 论坛账号,一键登录您的应用
|
<p className="text-base text-gray-500 dark:text-gray-400 sm:text-lg md:text-xl">
|
||||||
</TypographyLead>
|
基于 OAuth 2.0 协议,为您的应用快速接入 Q58
|
||||||
|
论坛统一身份认证,实现一键登录
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div className="flex gap-4">
|
<div className="flex gap-4">
|
||||||
<Link href="/sign-in">
|
<Link href="/sign-in">
|
||||||
<Button size="lg">
|
<Button size="lg" className="gap-2">
|
||||||
开始使用
|
开始使用
|
||||||
<ArrowRight className="ml-2 h-5 w-5" />
|
<ArrowRight className="h-5 w-5" />
|
||||||
</Button>
|
</Button>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
@ -46,18 +55,20 @@ export default function HomePage() {
|
|||||||
</Container>
|
</Container>
|
||||||
</Section>
|
</Section>
|
||||||
|
|
||||||
<Section>
|
{/* Features Section */}
|
||||||
|
<Section className="bg-white py-24 dark:bg-gray-900">
|
||||||
<Container>
|
<Container>
|
||||||
<div className="grid gap-8 md:grid-cols-3">
|
<div className="grid gap-8 md:grid-cols-3">
|
||||||
<Card>
|
<Card className="border-2 bg-white/50 transition-colors hover:border-primary/50 dark:bg-gray-800/50">
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle>简单集成</CardTitle>
|
<Code2 className="h-10 w-10 text-primary" />
|
||||||
<CardDescription>
|
<CardTitle className="text-xl">简单集成</CardTitle>
|
||||||
|
<CardDescription className="text-base">
|
||||||
只需几行代码,即可为您的应用添加 Q58 论坛账号登录功能
|
只需几行代码,即可为您的应用添加 Q58 论坛账号登录功能
|
||||||
</CardDescription>
|
</CardDescription>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent>
|
<CardContent>
|
||||||
<ul className="space-y-2">
|
<ul className="space-y-4 text-sm">
|
||||||
<li className="flex items-center gap-2">
|
<li className="flex items-center gap-2">
|
||||||
<CheckCircle2 className="h-5 w-5 text-green-500" />
|
<CheckCircle2 className="h-5 w-5 text-green-500" />
|
||||||
<span>标准 OAuth 2.0 协议</span>
|
<span>标准 OAuth 2.0 协议</span>
|
||||||
@ -74,15 +85,16 @@ export default function HomePage() {
|
|||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
<Card>
|
<Card className="border-2 bg-white/50 transition-colors hover:border-primary/50 dark:bg-gray-800/50">
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle>安全可靠</CardTitle>
|
<Lock className="h-10 w-10 text-primary" />
|
||||||
<CardDescription>
|
<CardTitle className="text-xl">安全可靠</CardTitle>
|
||||||
|
<CardDescription className="text-base">
|
||||||
采用业界最佳实践,确保您的应用和用户数据安全
|
采用业界最佳实践,确保您的应用和用户数据安全
|
||||||
</CardDescription>
|
</CardDescription>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent>
|
<CardContent>
|
||||||
<ul className="space-y-2">
|
<ul className="space-y-4 text-sm">
|
||||||
<li className="flex items-center gap-2">
|
<li className="flex items-center gap-2">
|
||||||
<CheckCircle2 className="h-5 w-5 text-green-500" />
|
<CheckCircle2 className="h-5 w-5 text-green-500" />
|
||||||
<span>HTTPS 加密传输</span>
|
<span>HTTPS 加密传输</span>
|
||||||
@ -99,15 +111,16 @@ export default function HomePage() {
|
|||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
<Card>
|
<Card className="border-2 bg-white/50 transition-colors hover:border-primary/50 dark:bg-gray-800/50">
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle>功能丰富</CardTitle>
|
<Users className="h-10 w-10 text-primary" />
|
||||||
<CardDescription>
|
<CardTitle className="text-xl">功能丰富</CardTitle>
|
||||||
|
<CardDescription className="text-base">
|
||||||
提供完整的用户信息和权限管理功能
|
提供完整的用户信息和权限管理功能
|
||||||
</CardDescription>
|
</CardDescription>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent>
|
<CardContent>
|
||||||
<ul className="space-y-2">
|
<ul className="space-y-4 text-sm">
|
||||||
<li className="flex items-center gap-2">
|
<li className="flex items-center gap-2">
|
||||||
<CheckCircle2 className="h-5 w-5 text-green-500" />
|
<CheckCircle2 className="h-5 w-5 text-green-500" />
|
||||||
<span>用户基本信息</span>
|
<span>用户基本信息</span>
|
||||||
@ -127,16 +140,18 @@ export default function HomePage() {
|
|||||||
</Container>
|
</Container>
|
||||||
</Section>
|
</Section>
|
||||||
|
|
||||||
<Section>
|
{/* Documentation Section */}
|
||||||
|
<Section className="border-t bg-gray-50 py-24 dark:bg-gray-800">
|
||||||
<Container>
|
<Container>
|
||||||
<Card>
|
<div className="mx-auto max-w-4xl">
|
||||||
<CardHeader>
|
<Card className="overflow-hidden border-2 p-6">
|
||||||
<CardTitle>快速开始</CardTitle>
|
<CardHeader className="bg-white dark:bg-gray-900">
|
||||||
<CardDescription>
|
<CardTitle className="text-2xl">快速开始</CardTitle>
|
||||||
|
<CardDescription className="text-base">
|
||||||
按照以下步骤,快速接入 Q58 Connect
|
按照以下步骤,快速接入 Q58 Connect
|
||||||
</CardDescription>
|
</CardDescription>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent>
|
<CardContent className="bg-white p-0 dark:bg-gray-900">
|
||||||
<Tabs defaultValue="auth" className="w-full">
|
<Tabs defaultValue="auth" className="w-full">
|
||||||
<TabsList className="grid w-full grid-cols-3">
|
<TabsList className="grid w-full grid-cols-3">
|
||||||
<TabsTrigger value="auth">发起授权</TabsTrigger>
|
<TabsTrigger value="auth">发起授权</TabsTrigger>
|
||||||
@ -232,19 +247,23 @@ const { access_token, expires_in } = await response.json();`}
|
|||||||
</Tabs>
|
</Tabs>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
|
</div>
|
||||||
</Container>
|
</Container>
|
||||||
</Section>
|
</Section>
|
||||||
|
|
||||||
<Section>
|
{/* CTA Section */}
|
||||||
|
<Section className="bg-white py-24 dark:bg-gray-900">
|
||||||
<Container>
|
<Container>
|
||||||
<div className="text-center">
|
<div className="text-center">
|
||||||
<TypographyH2>准备好了吗?</TypographyH2>
|
<h2 className="text-3xl font-bold">准备好了吗?</h2>
|
||||||
<TypographyMuted className="mt-2">
|
<p className="mt-2 text-gray-500 dark:text-gray-400">
|
||||||
创建一个应用,开始使用 Q58 Connect
|
创建一个应用,开始使用 Q58 Connect
|
||||||
</TypographyMuted>
|
</p>
|
||||||
<div className="mt-4">
|
<div className="mt-8">
|
||||||
<Link href="/sign-in">
|
<Link href="/sign-in">
|
||||||
<Button size="lg">立即开始</Button>
|
<Button size="lg" className="min-w-[200px]">
|
||||||
|
立即开始
|
||||||
|
</Button>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -252,9 +271,9 @@ const { access_token, expires_in } = await response.json();`}
|
|||||||
</Section>
|
</Section>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<footer className="border-t bg-white py-8 dark:bg-gray-800">
|
<footer className="border-t bg-white py-12 dark:bg-gray-900">
|
||||||
<Container>
|
<Container>
|
||||||
<div className="text-center text-gray-600 dark:text-gray-400">
|
<div className="text-center text-sm text-gray-500 dark:text-gray-400">
|
||||||
© 2024{" "}
|
© 2024{" "}
|
||||||
<a
|
<a
|
||||||
href="https://q58.club"
|
href="https://q58.club"
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { usePathname, useRouter } from "next/navigation";
|
import { usePathname, useRouter } from "next/navigation";
|
||||||
import { ChevronDown, User } from "lucide-react";
|
import { ChevronDown, Menu, User } from "lucide-react";
|
||||||
import { signOut } from "next-auth/react";
|
import { signOut } from "next-auth/react";
|
||||||
|
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
@ -38,7 +38,7 @@ export function HeaderClient({ initialUser }: HeaderClientProps) {
|
|||||||
if (!user) return null;
|
if (!user) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="ml-8 flex items-center space-x-1">
|
<div className="ml-8 hidden items-center space-x-1 md:flex">
|
||||||
<Link
|
<Link
|
||||||
href="/dashboard"
|
href="/dashboard"
|
||||||
className={cn(
|
className={cn(
|
||||||
@ -155,12 +155,140 @@ export function HeaderClient({ initialUser }: HeaderClientProps) {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 移动端导航菜单
|
||||||
|
const renderMobileMenu = () => {
|
||||||
|
if (!user) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DropdownMenu>
|
||||||
|
<DropdownMenuTrigger asChild>
|
||||||
|
<Button variant="ghost" size="icon" className="md:hidden">
|
||||||
|
<Menu className="h-5 w-5" />
|
||||||
|
</Button>
|
||||||
|
</DropdownMenuTrigger>
|
||||||
|
<DropdownMenuContent align="end" className="w-64">
|
||||||
|
<div className="flex items-center gap-3 border-b px-2 py-3">
|
||||||
|
<Avatar className="h-8 w-8">
|
||||||
|
<AvatarImage src={user.avatarUrl || undefined} />
|
||||||
|
<AvatarFallback>
|
||||||
|
{user.name?.charAt(0) || user.username?.charAt(0)}
|
||||||
|
</AvatarFallback>
|
||||||
|
</Avatar>
|
||||||
|
<div className="flex flex-col">
|
||||||
|
<span className="text-sm font-medium">
|
||||||
|
{user.name || user.username}
|
||||||
|
</span>
|
||||||
|
<span className="text-xs text-muted-foreground">
|
||||||
|
{user.email}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<DropdownMenuItem asChild>
|
||||||
|
<Link
|
||||||
|
href="/dashboard"
|
||||||
|
className={cn("w-full", pathname === "/dashboard" && "bg-accent")}
|
||||||
|
>
|
||||||
|
控制台
|
||||||
|
</Link>
|
||||||
|
</DropdownMenuItem>
|
||||||
|
<DropdownMenuItem asChild>
|
||||||
|
<Link
|
||||||
|
href="/dashboard/clients"
|
||||||
|
className={cn(
|
||||||
|
"w-full",
|
||||||
|
pathname.startsWith("/dashboard/clients") && "bg-accent",
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
应用管理
|
||||||
|
</Link>
|
||||||
|
</DropdownMenuItem>
|
||||||
|
<DropdownMenuItem asChild>
|
||||||
|
<Link
|
||||||
|
href="/dashboard/settings"
|
||||||
|
className={cn(
|
||||||
|
"w-full",
|
||||||
|
pathname === "/dashboard/settings" && "bg-accent",
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
设置
|
||||||
|
</Link>
|
||||||
|
</DropdownMenuItem>
|
||||||
|
{user.role === "ADMIN" && (
|
||||||
|
<>
|
||||||
|
<div className="my-1 h-px bg-border" />
|
||||||
|
<DropdownMenuItem asChild>
|
||||||
|
<Link
|
||||||
|
href="/admin"
|
||||||
|
className={cn("w-full", pathname === "/admin" && "bg-accent")}
|
||||||
|
>
|
||||||
|
管理后台
|
||||||
|
</Link>
|
||||||
|
</DropdownMenuItem>
|
||||||
|
<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>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
<div className="my-1 h-px bg-border" />
|
||||||
|
<DropdownMenuItem
|
||||||
|
onClick={handleSignOut}
|
||||||
|
className="text-red-600 focus:bg-red-50 focus:text-red-600 dark:focus:bg-red-950"
|
||||||
|
>
|
||||||
|
退出登录
|
||||||
|
</DropdownMenuItem>
|
||||||
|
</DropdownMenuContent>
|
||||||
|
</DropdownMenu>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex items-center space-x-4">
|
<div className="flex items-center space-x-4">
|
||||||
{renderNavLinks()}
|
{renderNavLinks()}
|
||||||
<ThemeToggle />
|
<ThemeToggle />
|
||||||
{user ? (
|
{user ? (
|
||||||
<div className="flex items-center gap-3">
|
<>
|
||||||
|
<div className="hidden items-center gap-3 md:flex">
|
||||||
<Avatar className="h-8 w-8">
|
<Avatar className="h-8 w-8">
|
||||||
<AvatarImage src={user.avatarUrl || undefined} />
|
<AvatarImage src={user.avatarUrl || undefined} />
|
||||||
<AvatarFallback>
|
<AvatarFallback>
|
||||||
@ -176,6 +304,8 @@ export function HeaderClient({ initialUser }: HeaderClientProps) {
|
|||||||
退出
|
退出
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
{renderMobileMenu()}
|
||||||
|
</>
|
||||||
) : (
|
) : (
|
||||||
<Button
|
<Button
|
||||||
variant="outline"
|
variant="outline"
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
|
|
||||||
import { getCurrentUser } from "@/lib/session";
|
import { getCurrentUser } from "@/lib/session";
|
||||||
|
import DynamicLogo from "@/components/dynamic-logo";
|
||||||
import { HeaderClient } from "@/components/layout/header-client";
|
import { HeaderClient } from "@/components/layout/header-client";
|
||||||
|
|
||||||
export async function Header() {
|
export async function Header() {
|
||||||
@ -12,7 +13,8 @@ export async function Header() {
|
|||||||
<div className="flex h-14 items-center justify-between">
|
<div className="flex h-14 items-center justify-between">
|
||||||
<div className="flex items-center">
|
<div className="flex items-center">
|
||||||
<Link href="/" className="flex items-center space-x-3">
|
<Link href="/" className="flex items-center space-x-3">
|
||||||
<h1 className="text-2xl font-bold text-[#25263A] dark:text-white">
|
<DynamicLogo />
|
||||||
|
<h1 className="hidden text-2xl font-bold text-[#25263A] dark:text-white sm:block">
|
||||||
Q58 Connect
|
Q58 Connect
|
||||||
</h1>
|
</h1>
|
||||||
</Link>
|
</Link>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user