import React, { createContext, useContext, useEffect, useState } from 'react'; import api, { setAccessToken } from './api'; import { getGlobalStorage } from './storage'; export interface AccessToken { token: string; expiresIn: number; tokenType?: string; scope?: string; expiresAt: number; } interface AuthContextType { authStatus: 'auth' | 'loading' | 'fail'; setToken: (token: AccessToken | undefined | null) => void; } const AuthContext = createContext(null!); export function AuthProvider({ children }: { children: React.ReactNode }) { const [authStatus, setAuthStatus] = useState<'auth' | 'loading' | 'fail'>('loading'); const setToken = (nextToken: AccessToken | undefined | null) => { // tokenCache = nextToken; if (nextToken && nextToken.token && nextToken.expiresIn) { // if (!tokenCache.expiresAt) { nextToken.expiresAt = nextToken.expiresIn + Date.now() / 1000; // } } else { nextToken = null; } if (nextToken) { setAuthStatus('auth'); getGlobalStorage().setObject("access_token", nextToken, nextToken.expiresIn); } else { setAuthStatus('fail'); getGlobalStorage().remove("access_token"); } setAccessToken(nextToken); }; useEffect(() => { const token = getGlobalStorage().getObject("access_token"); setToken(token); }, []); return ( {children} ); } export function useAuthContext() { const context = useContext(AuthContext); if (!context) { throw new Error('useAuthContext must be used within an AuthProvider'); } return context; } export function useAuth() { return useAuthContext(); } export async function signIn(mobile: string, password: string) { const { token, expires_in } = await api.post<{ token: string, expires_in: number, }>("/user/login", { mobile, password }); return { token, expiresIn: expires_in } as AccessToken; } export async function smsSignIn(mobile: string, captcha: string) { const { token, expires_in } = await api.post<{ token: string, expires_in: number, }>("/user/mobilelogin", { mobile, captcha }); return { token, expiresIn: expires_in } as AccessToken; } export async function signUp(info: { mobile: string; captcha: string; password: string; name: string; email: string; }) { const { token, expires_in } = await api.post<{ token: string, expires_in: number, }>("/user/register", info); return { token, expiresIn: expires_in } as AccessToken; } export async function signOut() { return api.get("/user/logout") }