From de477949a1ca87d3aa2fdf5a351fb6c0ec55cd15 Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Fri, 17 Apr 2026 18:01:16 +0000 Subject: [PATCH] Changes Co-authored-by: domfelipe <53182096+domfelipe@users.noreply.github.com> --- src/hooks/use-subscription-realtime.ts | 36 ++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/src/hooks/use-subscription-realtime.ts b/src/hooks/use-subscription-realtime.ts index d946923..57bee1d 100644 --- a/src/hooks/use-subscription-realtime.ts +++ b/src/hooks/use-subscription-realtime.ts @@ -1,21 +1,30 @@ "use client"; -import { useEffect } from "react"; +import { useEffect, useRef } from "react"; import { useQueryClient } from "@tanstack/react-query"; +import { toast } from "sonner"; import { supabase } from "@/integrations/supabase/client"; import { useAuth } from "@/hooks/use-auth"; +const ACTIVE_STATUSES = new Set(["active", "trialing"]); + /** * Subscribes to realtime changes on the user's subscription row. * When the payments webhook upserts a subscription, the affected * queries are invalidated so the UI updates without a page reload. + * + * Also surfaces a toast when the subscription transitions into an + * active state (active/trialing) so the user gets immediate feedback + * after a successful checkout. */ export function useSubscriptionRealtime() { const { user } = useAuth(); const queryClient = useQueryClient(); + const lastStatusRef = useRef(null); useEffect(() => { if (!user?.id) return; + lastStatusRef.current = null; const channel = supabase .channel(`subscriptions:user:${user.id}`) @@ -27,10 +36,33 @@ export function useSubscriptionRealtime() { table: "subscriptions", filter: `user_id=eq.${user.id}`, }, - () => { + (payload) => { queryClient.invalidateQueries({ queryKey: ["subscription", user.id] }); queryClient.invalidateQueries({ queryKey: ["has-active-subscription", user.id] }); queryClient.invalidateQueries({ queryKey: ["plan"] }); + + const newRow = (payload.new ?? null) as { status?: string } | null; + const newStatus = newRow?.status ?? null; + const prevStatus = lastStatusRef.current; + + if ( + newStatus && + ACTIVE_STATUSES.has(newStatus) && + prevStatus !== newStatus && + !(prevStatus && ACTIVE_STATUSES.has(prevStatus)) + ) { + if (newStatus === "trialing") { + toast.success("Período de teste ativado!", { + description: "Aproveite todos os recursos do seu plano.", + }); + } else { + toast.success("Assinatura ativada!", { + description: "Tudo pronto — seu plano já está liberado.", + }); + } + } + + lastStatusRef.current = newStatus; }, ) .subscribe();