Files
HoruxDespachosNuevo/apps/web/lib/hooks/use-subscription.ts

162 lines
4.8 KiB
TypeScript

'use client';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import * as subscriptionApi from '../api/subscription';
import { apiClient } from '../api/client';
/**
* Adaptador del catálogo despacho (`/planes/despacho`) al shape legacy que espera
* `/configuracion/suscripcion`: `{ plan, frequency, amount }[]`. El catálogo
* despacho tiene precios separados `monthly` / `firstYear` / `renewal` que aquí
* proyectamos como dos filas (`monthly` y `annual`) por plan, usando `firstYear`
* como precio anual cuando existe (precio "vitrina" de venta nueva).
*
* Mantiene la API pública del page sin migración invasiva — cuando se rehaga la
* página para soportar dualidad de precios firstYear/renewal nativamente, este
* adapter se puede borrar.
*/
interface DespachoPlanLimits {
plan: string;
monthly: number | null;
firstYear: number | null;
renewal: number | null;
permiteMonthly: boolean;
}
interface PlanPriceRow {
plan: string;
frequency: 'monthly' | 'annual';
amount: number;
}
export function usePlans() {
return useQuery<PlanPriceRow[]>({
queryKey: ['despacho-catalogo-as-plans'],
queryFn: async () => {
const res = await apiClient.get<{ data: DespachoPlanLimits[] }>('/planes/despacho');
const rows: PlanPriceRow[] = [];
for (const p of res.data.data) {
if (p.permiteMonthly && p.monthly != null) {
rows.push({ plan: p.plan, frequency: 'monthly', amount: p.monthly });
}
const annual = p.firstYear ?? p.renewal;
if (annual != null) {
rows.push({ plan: p.plan, frequency: 'annual', amount: annual });
}
}
return rows;
},
staleTime: 5 * 60 * 1000,
});
}
export function useSubscription(tenantId: string | undefined) {
return useQuery({
queryKey: ['subscription', tenantId],
queryFn: () => subscriptionApi.getSubscription(tenantId!),
enabled: !!tenantId,
staleTime: 5 * 60 * 1000,
});
}
export function usePaymentHistory(tenantId: string | undefined) {
return useQuery({
queryKey: ['payments', tenantId],
queryFn: () => subscriptionApi.getPaymentHistory(tenantId!),
enabled: !!tenantId,
staleTime: 60 * 1000,
});
}
export function useGeneratePaymentLink() {
return useMutation({
mutationFn: (tenantId: string) => subscriptionApi.generatePaymentLink(tenantId),
});
}
export function useMarkAsPaid() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: ({ tenantId, amount }: { tenantId: string; amount: number }) =>
subscriptionApi.markAsPaid(tenantId, amount),
onSuccess: (_, { tenantId }) => {
queryClient.invalidateQueries({ queryKey: ['subscription', tenantId] });
queryClient.invalidateQueries({ queryKey: ['payments', tenantId] });
},
});
}
// ============================================================================
// Self-serve hooks (actúan sobre el tenant del usuario autenticado)
// ============================================================================
export function useStartTrial() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: subscriptionApi.startTrial,
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['subscription'] });
},
});
}
export function useSubscribeMe() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: subscriptionApi.subscribeMe,
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['subscription'] });
},
});
}
export function useChangeMyPlan() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: subscriptionApi.changeMyPlan,
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['subscription'] });
},
});
}
export function useCancelMySubscription() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: subscriptionApi.cancelMySubscription,
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['subscription'] });
},
});
}
export function useUpgradeMe() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (plan: string) => subscriptionApi.upgradeMe(plan),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['subscription'] });
},
});
}
export function useCancelPendingUpgrade() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: subscriptionApi.cancelPendingUpgrade,
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['subscription'] });
},
});
}
export function useReactivateMe() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: subscriptionApi.reactivateMe,
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['subscription'] });
},
});
}