Q58Connect/src/app/()/page.tsx

414 lines
19 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import Link from "next/link";
import {
ArrowDownToLine,
ArrowRight,
CheckCircle2,
Code2,
Lock,
Send,
Users,
} from "lucide-react";
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
import { Button } from "@/components/ui/button";
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@/components/ui/card";
import { CodeBlock } from "@/components/ui/code-block";
import { Container } from "@/components/ui/container";
import { Section } from "@/components/ui/section";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { Header } from "@/components/layout/header";
export default function HomePage() {
return (
<div className="flex min-h-screen flex-col">
<Header />
<main className="flex-1">
{/* 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>
<div className="relative flex flex-col items-center justify-center space-y-8 text-center">
<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
</h1>
<div className="mx-auto max-w-[800px] px-4">
<p className="text-base text-gray-500 dark:text-gray-400 sm:text-lg md:text-xl">
OAuth 2.0 Q58
</p>
</div>
</div>
<div className="flex gap-4">
<Link href="/sign-in">
<Button size="lg" className="gap-2">
使
<ArrowRight className="h-5 w-5" />
</Button>
</Link>
</div>
</div>
</Container>
</Section>
{/* Features Section */}
<Section className="bg-white py-24 dark:bg-gray-900">
<Container>
<div className="grid gap-8 md:grid-cols-3">
<Card className="border-2 bg-white/50 transition-colors hover:border-primary/50 dark:bg-gray-800/50">
<CardHeader>
<Code2 className="h-10 w-10 text-primary" />
<CardTitle className="text-xl"></CardTitle>
<CardDescription className="text-base">
Q58
</CardDescription>
</CardHeader>
<CardContent>
<ul className="space-y-4 text-sm">
<li className="flex items-center gap-2">
<CheckCircle2 className="h-5 w-5 text-green-500" />
<span> OAuth 2.0 </span>
</li>
<li className="flex items-center gap-2">
<CheckCircle2 className="h-5 w-5 text-green-500" />
<span></span>
</li>
<li className="flex items-center gap-2">
<CheckCircle2 className="h-5 w-5 text-green-500" />
<span></span>
</li>
</ul>
</CardContent>
</Card>
<Card className="border-2 bg-white/50 transition-colors hover:border-primary/50 dark:bg-gray-800/50">
<CardHeader>
<Lock className="h-10 w-10 text-primary" />
<CardTitle className="text-xl"></CardTitle>
<CardDescription className="text-base">
</CardDescription>
</CardHeader>
<CardContent>
<ul className="space-y-4 text-sm">
<li className="flex items-center gap-2">
<CheckCircle2 className="h-5 w-5 text-green-500" />
<span>HTTPS </span>
</li>
<li className="flex items-center gap-2">
<CheckCircle2 className="h-5 w-5 text-green-500" />
<span>+</span>
</li>
<li className="flex items-center gap-2">
<CheckCircle2 className="h-5 w-5 text-green-500" />
<span>Serverless部署 SLA</span>
</li>
</ul>
</CardContent>
</Card>
<Card className="border-2 bg-white/50 transition-colors hover:border-primary/50 dark:bg-gray-800/50">
<CardHeader>
<Users className="h-10 w-10 text-primary" />
<CardTitle className="text-xl"></CardTitle>
<CardDescription className="text-base">
, , API用户信息和权限管理功能
</CardDescription>
</CardHeader>
<CardContent>
<ul className="space-y-4 text-sm">
<li className="flex items-center gap-2">
<CheckCircle2 className="h-5 w-5 text-green-500" />
<span>API </span>
</li>
<li className="flex items-center gap-2">
<CheckCircle2 className="h-5 w-5 text-green-500" />
<span></span>
</li>
<li className="flex items-center gap-2">
<CheckCircle2 className="h-5 w-5 text-green-500" />
<span> </span>
</li>
</ul>
</CardContent>
</Card>
</div>
</Container>
</Section>
{/* Documentation Section */}
<Section className="border-t bg-gray-50 py-24 dark:bg-gray-800">
<Container>
<div className="mx-auto max-w-4xl">
<Card className="overflow-hidden border-2 p-2 sm:p-6">
<CardHeader className="bg-white dark:bg-gray-900">
<CardTitle className="text-2xl">
()
</CardTitle>
<CardDescription className="text-base">
使Authorization
CodeOAuth 2.0
</CardDescription>
</CardHeader>
<CardContent className="overflow-x-auto bg-white p-0 dark:bg-gray-900">
<Tabs defaultValue="auth" className="w-full">
<TabsList className="grid w-full grid-cols-3">
<TabsTrigger value="auth">
<span className="flex h-5 w-6 items-center justify-center rounded-full bg-primary/10 text-primary">
1
</span>
</TabsTrigger>
<TabsTrigger value="callback">
<span className="flex h-5 w-6 items-center justify-center rounded-full bg-primary/10 text-primary">
2
</span>
</TabsTrigger>
<TabsTrigger value="userinfo">
<span className="flex h-5 w-6 items-center justify-center rounded-full bg-primary/10 text-primary">
3
</span>
</TabsTrigger>
</TabsList>
<div className="relative mt-6">
{/* <div className="absolute left-[3rem] top-0 h-full w-px bg-border" /> */}
<TabsContent value="auth" className="mt-4 space-y-4">
<Card className="border-2 shadow-sm transition-all hover:border-primary/50">
<CardHeader>
<div className="flex items-center gap-4">
<span className="flex h-8 w-8 items-center justify-center rounded-full bg-primary text-white">
1
</span>
<div>
<CardTitle>OAuth授权请求</CardTitle>
<CardDescription>
URL并重定向用户到授权页面
</CardDescription>
</div>
</div>
</CardHeader>
<CardContent className="space-y-4">
<Alert className="border-l-4 border-l-primary">
<Code2 className="h-4 w-4" />
<AlertTitle></AlertTitle>
<AlertDescription className="whitespace-pre-wrap break-words font-mono text-xs sm:text-sm">
GET https://connect.q58.club/oauth/authorize
</AlertDescription>
</Alert>
<div>
<h4 className="mb-2 font-medium"></h4>
<CodeBlock>
{`const authUrl = 'https://connect.q58.club/oauth/authorize?' +
new URLSearchParams({
response_type: 'code', // 必填,固定值为"code"
client_id: 'your_client_id', // 必填您的应用ID
redirect_uri: 'https://your-app.com/callback', // 必填,回调地址
scope: 'read_profile' // 可选权限范围默认read_profile
});
window.location.href = authUrl;`}
</CodeBlock>
</div>
<Alert className="border-green-500">
<ArrowDownToLine className="h-4 w-4" />
<AlertTitle></AlertTitle>
<AlertDescription>
<p className="mb-2">
</p>
<pre className="mt-2 overflow-x-auto whitespace-pre-wrap break-words rounded bg-gray-100 p-2 text-xs dark:bg-gray-800 sm:p-4 sm:text-sm">
<code className="text-sm">
https://your-app.com/callback?code=ac_xxxxxx...
</code>
</pre>
<div className="mt-4 space-y-2">
<p className="font-medium"></p>
<ul className="list-inside list-disc space-y-1 text-sm text-muted-foreground">
<li>ac_前缀 + 40</li>
<li>10</li>
<li>使使</li>
</ul>
</div>
</AlertDescription>
</Alert>
</CardContent>
</Card>
</TabsContent>
<TabsContent value="callback" className="mt-4 space-y-4">
<Card className="border-2 shadow-sm transition-all hover:border-primary/50">
<CardHeader>
<div className="flex items-center gap-4">
<span className="flex h-8 w-8 items-center justify-center rounded-full bg-primary text-white">
2
</span>
<div>
<CardTitle>使访</CardTitle>
<CardDescription>
使访
</CardDescription>
</div>
</div>
</CardHeader>
<CardContent className="space-y-4">
<Alert className="border-l-4 border-l-primary">
<Code2 className="h-4 w-4" />
<AlertTitle></AlertTitle>
<AlertDescription className="whitespace-pre-wrap break-words font-mono text-xs sm:text-sm">
POST
https://connect.q58.club/api/oauth/access_token
</AlertDescription>
</Alert>
<div>
<h4 className="mb-2 font-medium"></h4>
<CodeBlock>
{`const response = await fetch('https://connect.q58.club/api/oauth/access_token', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Basic ' + btoa(client_id + ':' + client_secret)
},
body: new URLSearchParams({
code: 'ac_xxxxx', // 必填,授权码
redirect_uri: 'https://your-app.com/callback' // 必填,与请求授权码时相同
})
});`}
</CodeBlock>
</div>
<Alert className="border-green-500">
<ArrowDownToLine className="h-4 w-4" />
<AlertTitle></AlertTitle>
<AlertDescription>
<pre className="mt-2 overflow-x-auto whitespace-pre-wrap break-words rounded bg-gray-100 p-2 text-xs dark:bg-gray-800 sm:p-4 sm:text-sm">
<code className="text-sm">
{`{
"access_token": "at_xxxxxxxx", // 访问令牌
"token_type": "bearer", // 令牌类型固定为bearer
"expires_in": 604800 // 令牌有效期单位秒7天
}`}
</code>
</pre>
</AlertDescription>
</Alert>
</CardContent>
</Card>
</TabsContent>
<TabsContent value="userinfo" className="mt-4 space-y-4">
<Card className="border-2 shadow-sm transition-all hover:border-primary/50">
<CardHeader>
<div className="flex items-center gap-4">
<span className="flex h-8 w-8 items-center justify-center rounded-full bg-primary text-white">
3
</span>
<div>
<CardTitle></CardTitle>
<CardDescription>
使访
</CardDescription>
</div>
</div>
</CardHeader>
<CardContent className="space-y-4">
<Alert className="border-l-4 border-l-primary">
<Code2 className="h-4 w-4" />
<AlertTitle></AlertTitle>
<AlertDescription className="whitespace-pre-wrap break-words font-mono text-xs sm:text-sm">
GET https://connect.q58.club/api/oauth/user
</AlertDescription>
</Alert>
<div>
<h4 className="mb-2 font-medium"></h4>
<CodeBlock>
{`const userInfo = await fetch('https://connect.q58.club/api/oauth/user', {
headers: {
'Authorization': \`Bearer \${access_token}\` // 使用获取到的访问令牌
}
}).then(res => res.json());`}
</CodeBlock>
</div>
<Alert className="border-green-500">
<ArrowDownToLine className="h-4 w-4" />
<AlertTitle></AlertTitle>
<AlertDescription>
<pre className="mt-2 overflow-x-auto whitespace-pre-wrap break-words rounded bg-gray-100 p-2 text-xs dark:bg-gray-800 sm:p-4 sm:text-sm">
<code className="text-sm">
{`{
"id": "user_xxx", // 用户唯一标识
"email": "user@example.com",// 邮箱地址
"username": "username", // 用户名
"name": "用户昵称", // 显示名称
"avatar_url": "https://...",// 头像URL
"admin": false, // 是否管理员
"groups": ["group1"], // 用户组
}`}
</code>
</pre>
</AlertDescription>
</Alert>
</CardContent>
</Card>
</TabsContent>
</div>
</Tabs>
</CardContent>
</Card>
</div>
</Container>
</Section>
{/* CTA Section */}
<Section className="bg-white py-24 dark:bg-gray-900">
<Container>
<div className="text-center">
<h2 className="text-3xl font-bold"></h2>
<p className="mt-2 text-gray-500 dark:text-gray-400">
使 Q58 Connect
</p>
<div className="mt-8">
<Link href="/sign-in">
<Button size="lg" className="min-w-[200px]">
</Button>
</Link>
</div>
</div>
</Container>
</Section>
</main>
<footer className="border-t bg-white py-12 dark:bg-gray-900">
<Container>
<div className="text-center text-sm text-gray-500 dark:text-gray-400">
© 2024{" "}
<a
href="https://q58.club"
className="text-[#25263A] hover:underline dark:text-[#A0A1B2]"
>
Q58论坛
</a>
.
</div>
</Container>
</footer>
</div>
);
}