162 lines
4.8 KiB
TypeScript
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'] });
|
|
},
|
|
});
|
|
}
|