aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/client/stores/auth.tsx
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-01-04 17:43:59 +0900
committernsfisis <nsfisis@gmail.com>2026-01-04 19:09:58 +0900
commitf8e4be9b36a16969ac53bd9ce12ce8064be10196 (patch)
treeb2cf350d2e2e52803ff809311effb40da767d859 /src/client/stores/auth.tsx
parente1c9e5e89bb91bca2586470c786510c3e1c03826 (diff)
downloadkioku-f8e4be9b36a16969ac53bd9ce12ce8064be10196.tar.gz
kioku-f8e4be9b36a16969ac53bd9ce12ce8064be10196.tar.zst
kioku-f8e4be9b36a16969ac53bd9ce12ce8064be10196.zip
refactor(client): migrate state management from React Context to Jotai
Replace AuthProvider and SyncProvider with Jotai atoms for more granular state management and better performance. This migration: - Creates atoms for auth, sync, decks, cards, noteTypes, and study state - Uses atomFamily for parameterized state (e.g., cards by deckId) - Introduces StoreInitializer component for subscription initialization - Updates all components and pages to use useAtomValue/useSetAtom - Updates all tests to use Jotai Provider with createStore pattern 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Diffstat (limited to 'src/client/stores/auth.tsx')
-rw-r--r--src/client/stores/auth.tsx92
1 files changed, 0 insertions, 92 deletions
diff --git a/src/client/stores/auth.tsx b/src/client/stores/auth.tsx
deleted file mode 100644
index 3f2681b..0000000
--- a/src/client/stores/auth.tsx
+++ /dev/null
@@ -1,92 +0,0 @@
-import {
- createContext,
- type ReactNode,
- useCallback,
- useContext,
- useEffect,
- useMemo,
- useState,
-} from "react";
-import { ApiClientError, apiClient, type User } from "../api/client";
-
-export interface AuthState {
- user: User | null;
- isAuthenticated: boolean;
- isLoading: boolean;
-}
-
-export interface AuthActions {
- login: (username: string, password: string) => Promise<void>;
- logout: () => void;
-}
-
-export type AuthContextValue = AuthState & AuthActions;
-
-const AuthContext = createContext<AuthContextValue | null>(null);
-
-export interface AuthProviderProps {
- children: ReactNode;
-}
-
-export function AuthProvider({ children }: AuthProviderProps) {
- const [user, setUser] = useState<User | null>(null);
- const [isLoading, setIsLoading] = useState(true);
- const [isAuthenticated, setIsAuthenticated] = useState(
- apiClient.isAuthenticated(),
- );
-
- const logout = useCallback(() => {
- apiClient.logout();
- setUser(null);
- setIsAuthenticated(false);
- }, []);
-
- // Check for existing auth on mount
- useEffect(() => {
- const tokens = apiClient.getTokens();
- if (tokens) {
- // We have tokens stored, but we don't have user info cached
- // For now, just set authenticated state. User info will be fetched when needed.
- // In a full implementation, we'd decode the JWT or call an API endpoint
- setIsLoading(false);
- } else {
- setIsLoading(false);
- }
- }, []);
-
- // Subscribe to session expired events from the API client
- useEffect(() => {
- return apiClient.onSessionExpired(() => {
- logout();
- });
- }, [logout]);
-
- const login = useCallback(async (username: string, password: string) => {
- const response = await apiClient.login(username, password);
- setUser(response.user);
- setIsAuthenticated(true);
- }, []);
-
- const value = useMemo<AuthContextValue>(
- () => ({
- user,
- isAuthenticated,
- isLoading,
- login,
- logout,
- }),
- [user, isAuthenticated, isLoading, login, logout],
- );
-
- return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
-}
-
-export function useAuth(): AuthContextValue {
- const context = useContext(AuthContext);
- if (!context) {
- throw new Error("useAuth must be used within an AuthProvider");
- }
- return context;
-}
-
-export { ApiClientError };