Files
audio-app/src/store/auth.tsx

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;
}