Migración desde workspace-v2/projects/template-saas/apps/frontend Este repositorio es parte del estándar multi-repo v2 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
75 lines
2.3 KiB
TypeScript
75 lines
2.3 KiB
TypeScript
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
|
import toast from 'react-hot-toast';
|
|
import { oauthApi, OAuthConnection } from '@/services/api';
|
|
import { AxiosError } from 'axios';
|
|
|
|
interface ApiError {
|
|
message: string;
|
|
statusCode?: number;
|
|
}
|
|
|
|
// Query keys
|
|
export const oauthKeys = {
|
|
all: ['oauth'] as const,
|
|
connections: () => [...oauthKeys.all, 'connections'] as const,
|
|
};
|
|
|
|
// Get OAuth authorization URL mutation
|
|
export function useOAuthUrl() {
|
|
return useMutation({
|
|
mutationFn: ({ provider, mode }: { provider: string; mode: 'login' | 'register' | 'link' }) =>
|
|
oauthApi.getAuthUrl(provider, mode),
|
|
onError: (error: AxiosError<ApiError>) => {
|
|
const message = error.response?.data?.message || 'Failed to get authorization URL';
|
|
toast.error(message);
|
|
},
|
|
});
|
|
}
|
|
|
|
// Process OAuth callback mutation
|
|
export function useOAuthCallback() {
|
|
return useMutation({
|
|
mutationFn: ({ provider, code, state, idToken, userData }: {
|
|
provider: string;
|
|
code: string;
|
|
state: string;
|
|
idToken?: string; // For Apple OAuth
|
|
userData?: string; // For Apple OAuth (first time only)
|
|
}) =>
|
|
oauthApi.handleCallback(provider, code, state, idToken, userData),
|
|
// Don't show toast here - OAuthCallbackPage handles the messaging
|
|
});
|
|
}
|
|
|
|
// Get OAuth connections query
|
|
export function useOAuthConnections() {
|
|
return useQuery({
|
|
queryKey: oauthKeys.connections(),
|
|
queryFn: oauthApi.getConnections,
|
|
staleTime: 5 * 60 * 1000, // 5 minutes
|
|
});
|
|
}
|
|
|
|
// Disconnect OAuth provider mutation
|
|
export function useDisconnectOAuth() {
|
|
const queryClient = useQueryClient();
|
|
|
|
return useMutation({
|
|
mutationFn: (provider: string) => oauthApi.disconnect(provider),
|
|
onSuccess: (_, provider) => {
|
|
queryClient.invalidateQueries({ queryKey: oauthKeys.connections() });
|
|
toast.success(`Disconnected ${provider} successfully`);
|
|
},
|
|
onError: (error: AxiosError<ApiError>) => {
|
|
const message = error.response?.data?.message || 'Failed to disconnect provider';
|
|
toast.error(message);
|
|
},
|
|
});
|
|
}
|
|
|
|
// Helper hook to check if a provider is connected
|
|
export function useIsProviderConnected(provider: string) {
|
|
const { data: connections } = useOAuthConnections();
|
|
return connections?.some((c: OAuthConnection) => c.provider === provider) ?? false;
|
|
}
|