77 lines
2.3 KiB
TypeScript
77 lines
2.3 KiB
TypeScript
import AsyncStorage from "@react-native-async-storage/async-storage";
|
|
import React, {
|
|
createContext,
|
|
useCallback,
|
|
useContext,
|
|
useEffect,
|
|
useMemo,
|
|
useState,
|
|
} from "react";
|
|
import { loginApi, signUpApi } from "../api/auth";
|
|
|
|
const ACCESS_TOKEN_KEY = "accessToken";
|
|
const REFRESH_TOKEN_KEY = "refreshToken";
|
|
|
|
export type AuthContextValue = {
|
|
accessToken: string | null;
|
|
isAuthed: boolean;
|
|
isHydrating: boolean;
|
|
signIn: (loginId: string, password: string) => Promise<void>;
|
|
signOut: () => Promise<void>;
|
|
signUp: (loginId: string, password: string) => Promise<void>;
|
|
};
|
|
|
|
const AuthContext = createContext<AuthContextValue | null>(null);
|
|
|
|
export function AuthProvider({ children }: { children: React.ReactNode }) {
|
|
const [accessToken, setAccessToken] = useState<string | null>(null);
|
|
const [isHydrating, setIsHydrating] = useState(true);
|
|
|
|
useEffect(() => {
|
|
(async () => {
|
|
const stored = await AsyncStorage.getItem(ACCESS_TOKEN_KEY);
|
|
setAccessToken(stored);
|
|
setIsHydrating(false);
|
|
})();
|
|
}, []);
|
|
|
|
const signIn = useCallback(async (loginId: string, password: string) => {
|
|
const response = await loginApi({ loginId, password });
|
|
setAccessToken(response.data.accessToken);
|
|
await AsyncStorage.setItem(ACCESS_TOKEN_KEY, response.data.accessToken);
|
|
await AsyncStorage.setItem(REFRESH_TOKEN_KEY, response.data.accessToken);
|
|
}, []);
|
|
|
|
const signOut = useCallback(async () => {
|
|
setAccessToken(null);
|
|
await AsyncStorage.removeItem(ACCESS_TOKEN_KEY);
|
|
}, []);
|
|
|
|
const signUp = useCallback(async (loginId: string, password: string) => {
|
|
const response = await signUpApi({ loginId, password });
|
|
setAccessToken(response.data.accessToken);
|
|
await AsyncStorage.setItem(ACCESS_TOKEN_KEY, response.data.accessToken);
|
|
await AsyncStorage.setItem(REFRESH_TOKEN_KEY, response.data.accessToken);
|
|
}, []);
|
|
|
|
const value = useMemo<AuthContextValue>(
|
|
() => ({
|
|
accessToken,
|
|
isAuthed: accessToken != null,
|
|
isHydrating,
|
|
signIn,
|
|
signOut,
|
|
signUp,
|
|
}),
|
|
[accessToken, isHydrating, signIn, signOut]
|
|
);
|
|
|
|
return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
|
|
}
|
|
|
|
export function useAuth(): AuthContextValue {
|
|
const ctx = useContext(AuthContext);
|
|
if (!ctx) throw new Error("useAuth must be used within AuthProvider");
|
|
return ctx;
|
|
}
|