This commit is contained in:
eric
2025-11-13 05:05:53 +08:00
parent cbdc65f56e
commit 891af61146
691 changed files with 83952 additions and 0 deletions

28
app/auth/error/page.tsx Normal file
View File

@@ -0,0 +1,28 @@
'use client'
import { useSearchParams } from 'next/navigation'
import { Suspense } from 'react'
function ErrorContent() {
const searchParams = useSearchParams()
const error = searchParams?.get('error')
return (
<div className="flex min-h-screen items-center justify-center">
<div className="text-center">
<h1 className="text-2xl font-bold mb-4"></h1>
<p className="text-muted-foreground mb-4">
{error || '发生未知错误'}
</p>
</div>
</div>
)
}
export default function ErrorPage() {
return (
<Suspense fallback={<div>Loading...</div>}>
<ErrorContent />
</Suspense>
)
}

126
app/auth/signin/page.tsx Normal file
View File

@@ -0,0 +1,126 @@
'use client'
import { signIn } from 'next-auth/react'
import { useSearchParams } from 'next/navigation'
import { Button } from "@/components/ui/button"
import { Icons } from "@/components/icons"
import { useState, Suspense } from 'react'
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/components/ui/card"
function SignInContent() {
const searchParams = useSearchParams()
const callbackUrl = searchParams?.get('callbackUrl') || '/admin'
const [isLoading, setIsLoading] = useState(false)
const handleSignIn = async () => {
try {
setIsLoading(true)
await signIn('github', {
callbackUrl,
redirect: true,
scope: 'repo'
})
} catch (error) {
setIsLoading(false)
console.error('登录失败:', error)
}
}
return (
<div className="grid min-h-screen w-full lg:grid-cols-2">
<div className="relative hidden h-full flex-col bg-muted p-10 text-white dark:border-r lg:flex">
<div className="absolute inset-0 bg-zinc-900" />
<div className="relative z-20 flex items-center text-lg font-medium">
<div className="flex items-center gap-2">
<div className="relative w-8 h-8 overflow-hidden rounded-md">
<img
src="/assets/images/alogo.png"
alt="Logo"
className="object-cover"
/>
</div>
<div className="flex flex-col">
<span className="text-lg font-semibold leading-none tracking-tight text-white">
NavSphere
</span>
</div>
</div>
</div>
<div className="relative z-20 mt-auto">
<blockquote className="space-y-2">
<p className="text-lg">
&ldquo;&rdquo;
</p>
<footer className="text-sm">NavSphere Team</footer>
</blockquote>
</div>
</div>
<div className="lg:p-8">
<div className="mx-auto flex h-full w-full flex-col justify-center space-y-6 sm:w-[350px]">
<Card>
<CardHeader className="space-y-1">
<CardTitle className="text-2xl text-center">
</CardTitle>
<CardDescription className="text-center">
使 GitHub 访
</CardDescription>
</CardHeader>
<CardContent className="grid gap-4">
<Button
onClick={handleSignIn}
className="w-full bg-[#24292F] hover:bg-[#24292F]/90 text-white"
disabled={isLoading}
>
{isLoading ? (
<>
<Icons.spinner className="mr-2 h-4 w-4 animate-spin" />
...
</>
) : (
<>
<Icons.github className="mr-2 h-4 w-4" />
GitHub
</>
)}
</Button>
</CardContent>
<CardFooter className="flex flex-wrap items-center justify-center gap-2">
<div className="text-sm text-muted-foreground">
{" "}
<a
href="/terms"
className="underline underline-offset-4 hover:text-primary"
>
</a>{" "}
{" "}
<a
href="/privacy"
className="underline underline-offset-4 hover:text-primary"
>
</a>
</div>
</CardFooter>
</Card>
</div>
</div>
</div>
)
}
export default function SignInPage() {
return (
<Suspense fallback={<div>Loading...</div>}>
<SignInContent />
</Suspense>
)
}