Files
cstb-next/src/components/auth/AuthProvider.tsx

77 lines
1.9 KiB
TypeScript

"use client"
import { onOpenUrl } from "@tauri-apps/plugin-deep-link"
import { useEffect } from "react"
import { useAuthStore } from "@/store/auth"
import { handleAuthCallback } from "@/utils/auth"
import { createClient } from "@/utils/supabase/client"
import { addToast } from "@heroui/react"
export function AuthProvider({ children }: { children: React.ReactNode }) {
const { checkSession, setSession, setLoading } = useAuthStore()
// 初始化时检查现有会话
useEffect(() => {
void checkSession()
}, [checkSession])
// 监听 deep-link 认证回调
useEffect(() => {
const unlisten = onOpenUrl(async (urls) => {
if (urls.length === 0) return
const url = urls[0]
if (!url.startsWith("cstb://auth")) return
setLoading(true)
try {
const session = await handleAuthCallback(url)
if (session) {
setSession(session)
addToast({
title: "登录成功",
description: `欢迎回来,${session.user.email || session.user.id}`,
})
} else {
addToast({
title: "登录失败",
description: "无法验证登录信息,请重试",
severity: "danger",
})
}
} catch (error) {
console.error("Auth callback error:", error)
addToast({
title: "登录失败",
description: error instanceof Error ? error.message : "未知错误",
severity: "danger",
})
} finally {
setLoading(false)
}
})
return () => {
void unlisten.then((fn) => fn())
}
}, [setSession, setLoading])
// 监听 Supabase 认证状态变化
useEffect(() => {
const supabase = createClient()
const {
data: { subscription },
} = supabase.auth.onAuthStateChange((_event, session) => {
setSession(session)
})
return () => {
subscription.unsubscribe()
}
}, [setSession])
return <>{children}</>
}