diff --git a/apps/x/apps/renderer/src/hooks/useBilling.ts b/apps/x/apps/renderer/src/hooks/useBilling.ts index b43a5ebe..aacfb767 100644 --- a/apps/x/apps/renderer/src/hooks/useBilling.ts +++ b/apps/x/apps/renderer/src/hooks/useBilling.ts @@ -25,7 +25,10 @@ export function useBilling(isRowboatConnected: boolean) { try { setIsLoading(true) const result = await window.ipc.invoke('billing:getInfo', null) - setBilling(result) + setBilling({ + ...result, + trialDaysRemaining: result.trialDaysRemaining ?? null, + }) } catch (error) { console.error('Failed to fetch billing info:', error) setBilling(null) @@ -34,6 +37,7 @@ export function useBilling(isRowboatConnected: boolean) { } }, [isRowboatConnected]) + // Fetch on mount / when connection state changes, and poll every 5 minutes useEffect(() => { fetchBilling() @@ -54,5 +58,15 @@ export function useBilling(isRowboatConnected: boolean) { } }, [fetchBilling, isRowboatConnected]) + // Also refetch when OAuth connection completes (e.g. on app launch auto-reconnect) + useEffect(() => { + const cleanup = window.ipc.on('oauth:didConnect', (event) => { + if (event.provider === 'rowboat') { + fetchBilling() + } + }) + return cleanup + }, [fetchBilling]) + return { billing, isLoading, refresh: fetchBilling } } diff --git a/apps/x/packages/shared/src/ipc.ts b/apps/x/packages/shared/src/ipc.ts index f2a012cf..94499338 100644 --- a/apps/x/packages/shared/src/ipc.ts +++ b/apps/x/packages/shared/src/ipc.ts @@ -564,7 +564,7 @@ const ipcSchemas = { userId: z.string().nullable(), subscriptionPlan: z.string().nullable(), subscriptionStatus: z.string().nullable(), - trialDaysRemaining: z.number().nullable(), + trialDaysRemaining: z.number().nullable().optional(), sanctionedCredits: z.number(), availableCredits: z.number(), }),