/** * Subscriptions Hooks * React hooks for subscription functionality using shared types */ import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query"; import { useAuthStore } from "@/features/auth/services/auth.store"; import { apiClient } from "@/core/api"; import type { Subscription, SubscriptionList, InvoiceList } from "@customer-portal/domain"; interface UseSubscriptionsOptions { status?: string; } /** * Hook to fetch all subscriptions */ export function useSubscriptions(options: UseSubscriptionsOptions = {}) { const { status } = options; const { tokens, isAuthenticated } = useAuthStore(); return useQuery({ queryKey: ["subscriptions", status], queryFn: async () => { if (!tokens?.accessToken) { throw new Error("Authentication required"); } const params = new URLSearchParams({ ...(status && { status }), }); const res = await apiClient.get( `/subscriptions?${params}` ); return res.data as SubscriptionList | Subscription[]; }, staleTime: 5 * 60 * 1000, // 5 minutes gcTime: 10 * 60 * 1000, // 10 minutes enabled: isAuthenticated && !!tokens?.accessToken, }); } /** * Hook to fetch active subscriptions only */ export function useActiveSubscriptions() { const { tokens, isAuthenticated } = useAuthStore(); return useQuery({ queryKey: ["subscriptions", "active"], queryFn: async () => { if (!tokens?.accessToken) { throw new Error("Authentication required"); } const res = await apiClient.get(`/subscriptions/active`); return res.data as Subscription[]; }, staleTime: 5 * 60 * 1000, // 5 minutes gcTime: 10 * 60 * 1000, // 10 minutes enabled: isAuthenticated && !!tokens?.accessToken, }); } /** * Hook to fetch subscription statistics */ export function useSubscriptionStats() { const { tokens, isAuthenticated } = useAuthStore(); return useQuery<{ total: number; active: number; suspended: number; cancelled: number; pending: number; }>({ queryKey: ["subscriptions", "stats"], queryFn: async () => { if (!tokens?.accessToken) { throw new Error("Authentication required"); } const res = await apiClient.get<{ total: number; active: number; suspended: number; cancelled: number; pending: number; }>(`/subscriptions/stats`); return res.data as { total: number; active: number; suspended: number; cancelled: number; pending: number; }; }, staleTime: 5 * 60 * 1000, // 5 minutes gcTime: 10 * 60 * 1000, // 10 minutes enabled: isAuthenticated && !!tokens?.accessToken, }); } /** * Hook to fetch a specific subscription */ export function useSubscription(subscriptionId: number) { const { tokens, isAuthenticated } = useAuthStore(); return useQuery({ queryKey: ["subscription", subscriptionId], queryFn: async () => { if (!tokens?.accessToken) { throw new Error("Authentication required"); } const res = await apiClient.get(`/subscriptions/${subscriptionId}`); return res.data as Subscription; }, staleTime: 5 * 60 * 1000, // 5 minutes gcTime: 10 * 60 * 1000, // 10 minutes enabled: isAuthenticated && !!tokens?.accessToken, }); } /** * Hook to fetch subscription invoices */ export function useSubscriptionInvoices( subscriptionId: number, options: { page?: number; limit?: number } = {} ) { const { page = 1, limit = 10 } = options; const { tokens, isAuthenticated } = useAuthStore(); return useQuery({ queryKey: ["subscription-invoices", subscriptionId, page, limit], queryFn: async () => { if (!tokens?.accessToken) { throw new Error("Authentication required"); } const params = new URLSearchParams({ page: page.toString(), limit: limit.toString(), }); const res = await apiClient.get( `/subscriptions/${subscriptionId}/invoices?${params}` ); return unwrap(res) as InvoiceList; }, staleTime: 60 * 1000, // 1 minute gcTime: 5 * 60 * 1000, // 5 minutes enabled: isAuthenticated && !!tokens?.accessToken && !!subscriptionId, }); } /** * Hook to perform subscription actions (suspend, resume, cancel, etc.) */ export function useSubscriptionAction() { const queryClient = useQueryClient(); return useMutation({ mutationFn: async ({ id, action }: { id: number; action: string }) => { const res = await apiClient.post(`/subscriptions/${id}/actions`, { action }); return unwrap(res); }, onSuccess: (_, { id }) => { // Invalidate relevant queries after successful action void queryClient.invalidateQueries({ queryKey: ["subscriptions"] }); void queryClient.invalidateQueries({ queryKey: ["subscription", id] }); }, }); }