Initial commit: SmoothSchedule multi-tenant scheduling platform
This commit includes: - Django backend with multi-tenancy (django-tenants) - React + TypeScript frontend with Vite - Platform administration API with role-based access control - Authentication system with token-based auth - Quick login dev tools for testing different user roles - CORS and CSRF configuration for local development - Docker development environment setup 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
154
legacy_reference/frontend/src/hooks/usePayments.ts
Normal file
154
legacy_reference/frontend/src/hooks/usePayments.ts
Normal file
@@ -0,0 +1,154 @@
|
||||
/**
|
||||
* Payment Hooks
|
||||
* React Query hooks for payment configuration management
|
||||
*/
|
||||
|
||||
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
import * as paymentsApi from '../api/payments';
|
||||
|
||||
// ============================================================================
|
||||
// Query Keys
|
||||
// ============================================================================
|
||||
|
||||
export const paymentKeys = {
|
||||
all: ['payments'] as const,
|
||||
config: () => [...paymentKeys.all, 'config'] as const,
|
||||
apiKeys: () => [...paymentKeys.all, 'apiKeys'] as const,
|
||||
connectStatus: () => [...paymentKeys.all, 'connectStatus'] as const,
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
// Unified Configuration Hook
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* Get unified payment configuration status.
|
||||
* Returns the complete payment setup for the business.
|
||||
*/
|
||||
export const usePaymentConfig = () => {
|
||||
return useQuery({
|
||||
queryKey: paymentKeys.config(),
|
||||
queryFn: () => paymentsApi.getPaymentConfig().then(res => res.data),
|
||||
staleTime: 30 * 1000, // 30 seconds
|
||||
});
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
// API Keys Hooks (Free Tier)
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* Get current API key configuration (masked).
|
||||
*/
|
||||
export const useApiKeys = () => {
|
||||
return useQuery({
|
||||
queryKey: paymentKeys.apiKeys(),
|
||||
queryFn: () => paymentsApi.getApiKeys().then(res => res.data),
|
||||
staleTime: 30 * 1000,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Validate API keys without saving.
|
||||
*/
|
||||
export const useValidateApiKeys = () => {
|
||||
return useMutation({
|
||||
mutationFn: ({ secretKey, publishableKey }: { secretKey: string; publishableKey: string }) =>
|
||||
paymentsApi.validateApiKeys(secretKey, publishableKey).then(res => res.data),
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Save API keys.
|
||||
*/
|
||||
export const useSaveApiKeys = () => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: ({ secretKey, publishableKey }: { secretKey: string; publishableKey: string }) =>
|
||||
paymentsApi.saveApiKeys(secretKey, publishableKey).then(res => res.data),
|
||||
onSuccess: () => {
|
||||
// Invalidate payment config to refresh status
|
||||
queryClient.invalidateQueries({ queryKey: paymentKeys.config() });
|
||||
queryClient.invalidateQueries({ queryKey: paymentKeys.apiKeys() });
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Re-validate stored API keys.
|
||||
*/
|
||||
export const useRevalidateApiKeys = () => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: () => paymentsApi.revalidateApiKeys().then(res => res.data),
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({ queryKey: paymentKeys.config() });
|
||||
queryClient.invalidateQueries({ queryKey: paymentKeys.apiKeys() });
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Delete stored API keys.
|
||||
*/
|
||||
export const useDeleteApiKeys = () => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: () => paymentsApi.deleteApiKeys().then(res => res.data),
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({ queryKey: paymentKeys.config() });
|
||||
queryClient.invalidateQueries({ queryKey: paymentKeys.apiKeys() });
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
// Stripe Connect Hooks (Paid Tiers)
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* Get current Connect account status.
|
||||
*/
|
||||
export const useConnectStatus = () => {
|
||||
return useQuery({
|
||||
queryKey: paymentKeys.connectStatus(),
|
||||
queryFn: () => paymentsApi.getConnectStatus().then(res => res.data),
|
||||
staleTime: 30 * 1000,
|
||||
// Only fetch if we might have a Connect account
|
||||
enabled: true,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Initiate Connect account onboarding.
|
||||
*/
|
||||
export const useConnectOnboarding = () => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: ({ refreshUrl, returnUrl }: { refreshUrl: string; returnUrl: string }) =>
|
||||
paymentsApi.initiateConnectOnboarding(refreshUrl, returnUrl).then(res => res.data),
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({ queryKey: paymentKeys.config() });
|
||||
queryClient.invalidateQueries({ queryKey: paymentKeys.connectStatus() });
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Refresh Connect onboarding link.
|
||||
*/
|
||||
export const useRefreshConnectLink = () => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: ({ refreshUrl, returnUrl }: { refreshUrl: string; returnUrl: string }) =>
|
||||
paymentsApi.refreshConnectOnboardingLink(refreshUrl, returnUrl).then(res => res.data),
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({ queryKey: paymentKeys.connectStatus() });
|
||||
},
|
||||
});
|
||||
};
|
||||
Reference in New Issue
Block a user