/** * Platform Settings Hooks */ import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; import apiClient from '../api/client'; export interface PlatformSettings { stripe_secret_key_masked: string; stripe_publishable_key_masked: string; stripe_webhook_secret_masked: string; stripe_account_id: string; stripe_account_name: string; stripe_keys_validated_at: string | null; stripe_validation_error: string; has_stripe_keys: boolean; stripe_keys_from_env: boolean; email_check_interval_minutes: number; updated_at: string; } export interface GeneralSettingsUpdate { email_check_interval_minutes?: number; } export interface StripeKeysUpdate { stripe_secret_key?: string; stripe_publishable_key?: string; stripe_webhook_secret?: string; } export interface SubscriptionPlan { id: number; name: string; description: string; plan_type: 'base' | 'addon'; stripe_product_id: string; stripe_price_id: string; price_monthly: string | null; price_yearly: string | null; business_tier: string; features: string[]; limits: Record; permissions: Record; transaction_fee_percent: string; transaction_fee_fixed: string; // Communication pricing sms_enabled: boolean; sms_price_per_message_cents: number; masked_calling_enabled: boolean; masked_calling_price_per_minute_cents: number; proxy_number_enabled: boolean; proxy_number_monthly_fee_cents: number; // Default credit settings default_auto_reload_enabled: boolean; default_auto_reload_threshold_cents: number; default_auto_reload_amount_cents: number; is_active: boolean; is_public: boolean; is_most_popular: boolean; show_price: boolean; created_at: string; updated_at: string; } export interface SubscriptionPlanCreate { name: string; description?: string; plan_type?: 'base' | 'addon'; price_monthly?: number | null; price_yearly?: number | null; business_tier?: string; features?: string[]; limits?: Record; permissions?: Record; transaction_fee_percent?: number; transaction_fee_fixed?: number; // Communication pricing sms_enabled?: boolean; sms_price_per_message_cents?: number; masked_calling_enabled?: boolean; masked_calling_price_per_minute_cents?: number; proxy_number_enabled?: boolean; proxy_number_monthly_fee_cents?: number; // Default credit settings default_auto_reload_enabled?: boolean; default_auto_reload_threshold_cents?: number; default_auto_reload_amount_cents?: number; is_active?: boolean; is_public?: boolean; is_most_popular?: boolean; show_price?: boolean; create_stripe_product?: boolean; stripe_product_id?: string; stripe_price_id?: string; } /** * Hook to get platform settings */ export const usePlatformSettings = () => { return useQuery({ queryKey: ['platformSettings'], queryFn: async () => { const { data } = await apiClient.get('/platform/settings/'); return data; }, staleTime: 5 * 60 * 1000, // 5 minutes }); }; /** * Hook to update general platform settings */ export const useUpdateGeneralSettings = () => { const queryClient = useQueryClient(); return useMutation({ mutationFn: async (settings: GeneralSettingsUpdate) => { const { data } = await apiClient.post('/platform/settings/general/', settings); return data; }, onSuccess: (data) => { queryClient.setQueryData(['platformSettings'], data); }, }); }; /** * Hook to update platform Stripe keys */ export const useUpdateStripeKeys = () => { const queryClient = useQueryClient(); return useMutation({ mutationFn: async (keys: StripeKeysUpdate) => { const { data } = await apiClient.post('/platform/settings/stripe/keys/', keys); return data; }, onSuccess: (data) => { queryClient.setQueryData(['platformSettings'], data); }, }); }; /** * Hook to validate platform Stripe keys */ export const useValidateStripeKeys = () => { const queryClient = useQueryClient(); return useMutation({ mutationFn: async () => { const { data } = await apiClient.post('/platform/settings/stripe/validate/'); return data; }, onSuccess: (data) => { if (data.settings) { queryClient.setQueryData(['platformSettings'], data.settings); } }, }); }; /** * Hook to get subscription plans */ export const useSubscriptionPlans = () => { return useQuery({ queryKey: ['subscriptionPlans'], queryFn: async () => { const { data } = await apiClient.get('/platform/subscription-plans/'); return data; }, staleTime: 5 * 60 * 1000, }); }; /** * Hook to create a subscription plan */ export const useCreateSubscriptionPlan = () => { const queryClient = useQueryClient(); return useMutation({ mutationFn: async (plan: SubscriptionPlanCreate) => { const { data } = await apiClient.post('/platform/subscription-plans/', plan); return data; }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['subscriptionPlans'] }); }, }); }; /** * Hook to update a subscription plan */ export const useUpdateSubscriptionPlan = () => { const queryClient = useQueryClient(); return useMutation({ mutationFn: async ({ id, ...updates }: Partial & { id: number }) => { const { data } = await apiClient.patch(`/platform/subscription-plans/${id}/`, updates); return data; }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['subscriptionPlans'] }); }, }); }; /** * Hook to delete a subscription plan */ export const useDeleteSubscriptionPlan = () => { const queryClient = useQueryClient(); return useMutation({ mutationFn: async (id: number) => { const { data } = await apiClient.delete(`/platform/subscription-plans/${id}/`); return data; }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['subscriptionPlans'] }); }, }); }; /** * Hook to sync plans with Stripe */ export const useSyncPlansWithStripe = () => { const queryClient = useQueryClient(); return useMutation({ mutationFn: async () => { const { data } = await apiClient.post('/platform/subscription-plans/sync_with_stripe/'); return data; }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['subscriptionPlans'] }); }, }); }; /** * Hook to sync a plan's permissions to all tenants on that plan */ export const useSyncPlanToTenants = () => { return useMutation({ mutationFn: async (planId: number) => { const { data } = await apiClient.post(`/platform/subscription-plans/${planId}/sync_tenants/`); return data as { message: string; tenant_count: number }; }, }); };