mirror of
https://github.com/siteboon/claudecodeui.git
synced 2026-06-03 02:55:39 +08:00
refactor: move provider auth status management to custom hook
This commit is contained in:
109
src/components/provider-auth/hooks/useProviderAuthStatus.ts
Normal file
109
src/components/provider-auth/hooks/useProviderAuthStatus.ts
Normal file
@@ -0,0 +1,109 @@
|
||||
import { useCallback, useState } from 'react';
|
||||
import { authenticatedFetch } from '../../../utils/api';
|
||||
import {
|
||||
CLI_AUTH_STATUS_ENDPOINTS,
|
||||
CLI_PROVIDERS,
|
||||
createInitialProviderAuthStatusMap,
|
||||
} from '../types';
|
||||
import type {
|
||||
CliProvider,
|
||||
ProviderAuthStatus,
|
||||
ProviderAuthStatusMap,
|
||||
} from '../types';
|
||||
|
||||
type ProviderAuthStatusPayload = {
|
||||
authenticated?: boolean;
|
||||
email?: string | null;
|
||||
method?: string | null;
|
||||
error?: string | null;
|
||||
};
|
||||
|
||||
const FALLBACK_STATUS_ERROR = 'Failed to check authentication status';
|
||||
const FALLBACK_UNKNOWN_ERROR = 'Unknown error';
|
||||
|
||||
const toErrorMessage = (error: unknown): string => (
|
||||
error instanceof Error ? error.message : FALLBACK_UNKNOWN_ERROR
|
||||
);
|
||||
|
||||
const toProviderAuthStatus = (
|
||||
payload: ProviderAuthStatusPayload,
|
||||
fallbackError: string | null = null,
|
||||
): ProviderAuthStatus => ({
|
||||
authenticated: Boolean(payload.authenticated),
|
||||
email: payload.email ?? null,
|
||||
method: payload.method ?? null,
|
||||
error: payload.error ?? fallbackError,
|
||||
loading: false,
|
||||
});
|
||||
|
||||
type UseProviderAuthStatusOptions = {
|
||||
initialLoading?: boolean;
|
||||
};
|
||||
|
||||
export function useProviderAuthStatus(
|
||||
{ initialLoading = true }: UseProviderAuthStatusOptions = {},
|
||||
) {
|
||||
const [providerAuthStatus, setProviderAuthStatus] = useState<ProviderAuthStatusMap>(() => (
|
||||
createInitialProviderAuthStatusMap(initialLoading)
|
||||
));
|
||||
|
||||
const setProviderLoading = useCallback((provider: CliProvider) => {
|
||||
setProviderAuthStatus((previous) => ({
|
||||
...previous,
|
||||
[provider]: {
|
||||
...previous[provider],
|
||||
loading: true,
|
||||
error: null,
|
||||
},
|
||||
}));
|
||||
}, []);
|
||||
|
||||
const setProviderStatus = useCallback((provider: CliProvider, status: ProviderAuthStatus) => {
|
||||
setProviderAuthStatus((previous) => ({
|
||||
...previous,
|
||||
[provider]: status,
|
||||
}));
|
||||
}, []);
|
||||
|
||||
const checkProviderAuthStatus = useCallback(async (provider: CliProvider) => {
|
||||
setProviderLoading(provider);
|
||||
|
||||
try {
|
||||
const response = await authenticatedFetch(CLI_AUTH_STATUS_ENDPOINTS[provider]);
|
||||
|
||||
if (!response.ok) {
|
||||
setProviderStatus(provider, {
|
||||
authenticated: false,
|
||||
email: null,
|
||||
method: null,
|
||||
loading: false,
|
||||
error: FALLBACK_STATUS_ERROR,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const payload = (await response.json()) as ProviderAuthStatusPayload;
|
||||
setProviderStatus(provider, toProviderAuthStatus(payload));
|
||||
} catch (caughtError) {
|
||||
console.error(`Error checking ${provider} auth status:`, caughtError);
|
||||
setProviderStatus(provider, {
|
||||
authenticated: false,
|
||||
email: null,
|
||||
method: null,
|
||||
loading: false,
|
||||
error: toErrorMessage(caughtError),
|
||||
});
|
||||
}
|
||||
}, [setProviderLoading, setProviderStatus]);
|
||||
|
||||
const refreshProviderAuthStatuses = useCallback(async (providers: CliProvider[] = CLI_PROVIDERS) => {
|
||||
await Promise.all(providers.map((provider) => checkProviderAuthStatus(provider)));
|
||||
}, [checkProviderAuthStatus]);
|
||||
|
||||
return {
|
||||
providerAuthStatus,
|
||||
setProviderAuthStatus,
|
||||
checkProviderAuthStatus,
|
||||
refreshProviderAuthStatuses,
|
||||
};
|
||||
}
|
||||
@@ -1 +1,27 @@
|
||||
export type CliProvider = 'claude' | 'cursor' | 'codex' | 'gemini';
|
||||
|
||||
export type ProviderAuthStatus = {
|
||||
authenticated: boolean;
|
||||
email: string | null;
|
||||
method: string | null;
|
||||
error: string | null;
|
||||
loading: boolean;
|
||||
};
|
||||
|
||||
export type ProviderAuthStatusMap = Record<CliProvider, ProviderAuthStatus>;
|
||||
|
||||
export const CLI_PROVIDERS: CliProvider[] = ['claude', 'cursor', 'codex', 'gemini'];
|
||||
|
||||
export const CLI_AUTH_STATUS_ENDPOINTS: Record<CliProvider, string> = {
|
||||
claude: '/api/cli/claude/status',
|
||||
cursor: '/api/cli/cursor/status',
|
||||
codex: '/api/cli/codex/status',
|
||||
gemini: '/api/cli/gemini/status',
|
||||
};
|
||||
|
||||
export const createInitialProviderAuthStatusMap = (loading = true): ProviderAuthStatusMap => ({
|
||||
claude: { authenticated: false, email: null, method: null, error: null, loading },
|
||||
cursor: { authenticated: false, email: null, method: null, error: null, loading },
|
||||
codex: { authenticated: false, email: null, method: null, error: null, loading },
|
||||
gemini: { authenticated: false, email: null, method: null, error: null, loading },
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user