/** * Subscriptions Hooks * React hooks for subscription functionality using shared types */ import { useQuery } from "@tanstack/react-query"; import { apiClient, queryKeys, getDataOrDefault, getDataOrThrow, getNullableData } from "@/lib/api"; import { useAuthSession } from "@/features/auth/services"; import type { InvoiceList, Subscription, SubscriptionList } from "@customer-portal/domain/billing"; interface UseSubscriptionsOptions { status?: string; } const emptySubscriptionList: SubscriptionList = { subscriptions: [], totalCount: 0, }; const emptyStats = { total: 0, active: 0, completed: 0, cancelled: 0, }; const emptyInvoiceList: InvoiceList = { invoices: [], pagination: { page: 1, totalItems: 0, totalPages: 0, }, }; function toSubscriptionList(payload?: SubscriptionList | Subscription[] | null): SubscriptionList { if (!payload) { return emptySubscriptionList; } if (Array.isArray(payload)) { return { subscriptions: payload, totalCount: payload.length, }; } return payload; } /** * Hook to fetch all subscriptions */ export function useSubscriptions(options: UseSubscriptionsOptions = {}) { const { status } = options; const { isAuthenticated } = useAuthSession(); return useQuery({ queryKey: queryKeys.subscriptions.list(status ? { status } : undefined), queryFn: async () => { const response = await apiClient.GET( "/api/subscriptions", status ? { params: { query: { status } } } : undefined ); return toSubscriptionList( getDataOrThrow(response, "Failed to load subscriptions") ); }, staleTime: 5 * 60 * 1000, gcTime: 10 * 60 * 1000, enabled: isAuthenticated, }); } /** * Hook to fetch active subscriptions only */ export function useActiveSubscriptions() { const { isAuthenticated } = useAuthSession(); return useQuery({ queryKey: queryKeys.subscriptions.active(), queryFn: async () => { const response = await apiClient.GET("/api/subscriptions/active"); return getDataOrThrow(response, "Failed to load active subscriptions"); }, staleTime: 5 * 60 * 1000, gcTime: 10 * 60 * 1000, enabled: isAuthenticated, }); } /** * Hook to fetch subscription statistics */ export function useSubscriptionStats() { const { isAuthenticated } = useAuthSession(); return useQuery({ queryKey: queryKeys.subscriptions.stats(), queryFn: async () => { const response = await apiClient.GET("/api/subscriptions/stats"); return getDataOrThrow(response, "Failed to load subscription statistics"); }, staleTime: 5 * 60 * 1000, gcTime: 10 * 60 * 1000, enabled: isAuthenticated, }); } /** * Hook to fetch a specific subscription */ export function useSubscription(subscriptionId: number) { const { isAuthenticated } = useAuthSession(); return useQuery({ queryKey: queryKeys.subscriptions.detail(String(subscriptionId)), queryFn: async () => { const response = await apiClient.GET("/api/subscriptions/{id}", { params: { path: { id: subscriptionId } }, }); return getDataOrThrow(response, "Failed to load subscription details"); }, staleTime: 5 * 60 * 1000, gcTime: 10 * 60 * 1000, enabled: isAuthenticated && subscriptionId > 0, }); } /** * Hook to fetch subscription invoices */ export function useSubscriptionInvoices( subscriptionId: number, options: { page?: number; limit?: number } = {} ) { const { page = 1, limit = 10 } = options; const { isAuthenticated } = useAuthSession(); return useQuery({ queryKey: queryKeys.subscriptions.invoices(subscriptionId, { page, limit }), queryFn: async () => { const response = await apiClient.GET("/api/subscriptions/{id}/invoices", { params: { path: { id: subscriptionId }, query: { page, limit }, }, }); return getDataOrThrow(response, "Failed to load subscription invoices"); }, staleTime: 60 * 1000, gcTime: 5 * 60 * 1000, enabled: isAuthenticated && subscriptionId > 0, }); }