template-saas-frontend-v2/src/hooks/useMlm.ts
Adrian Flores Cortes eff0f70b7f [SAAS-021] feat: Implement MLM module frontend
- 4 API services: structures, ranks, nodes, commissions
- 30+ React Query hooks in useMlm.ts
- My network/dashboard hooks for user experience
- Tree visualization support hooks

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 06:48:55 -06:00

303 lines
8.2 KiB
TypeScript

import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import {
structuresApi,
ranksApi,
nodesApi,
commissionsApi,
type StructureFilters,
type CreateStructureDto,
type UpdateStructureDto,
type RankFilters,
type CreateRankDto,
type UpdateRankDto,
type NodeFilters,
type CreateNodeDto,
type UpdateNodeDto,
type NodeStatus,
type CommissionFilters,
type CalculateCommissionsDto,
type CommissionStatus,
} from '@/services/mlm';
// ============================================
// Structures Hooks
// ============================================
export function useStructures(filters?: StructureFilters) {
return useQuery({
queryKey: ['mlm', 'structures', filters],
queryFn: () => structuresApi.list(filters),
});
}
export function useStructure(id: string) {
return useQuery({
queryKey: ['mlm', 'structures', id],
queryFn: () => structuresApi.get(id),
enabled: !!id,
});
}
export function useCreateStructure() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (data: CreateStructureDto) => structuresApi.create(data),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['mlm', 'structures'] });
},
});
}
export function useUpdateStructure() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: ({ id, data }: { id: string; data: UpdateStructureDto }) =>
structuresApi.update(id, data),
onSuccess: (_, { id }) => {
queryClient.invalidateQueries({ queryKey: ['mlm', 'structures'] });
queryClient.invalidateQueries({ queryKey: ['mlm', 'structures', id] });
},
});
}
export function useDeleteStructure() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (id: string) => structuresApi.delete(id),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['mlm', 'structures'] });
},
});
}
// ============================================
// Ranks Hooks
// ============================================
export function useRanks(filters?: RankFilters) {
return useQuery({
queryKey: ['mlm', 'ranks', filters],
queryFn: () => ranksApi.list(filters),
});
}
export function useRank(id: string) {
return useQuery({
queryKey: ['mlm', 'ranks', id],
queryFn: () => ranksApi.get(id),
enabled: !!id,
});
}
export function useCreateRank() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (data: CreateRankDto) => ranksApi.create(data),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['mlm', 'ranks'] });
},
});
}
export function useUpdateRank() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: ({ id, data }: { id: string; data: UpdateRankDto }) =>
ranksApi.update(id, data),
onSuccess: (_, { id }) => {
queryClient.invalidateQueries({ queryKey: ['mlm', 'ranks'] });
queryClient.invalidateQueries({ queryKey: ['mlm', 'ranks', id] });
},
});
}
export function useDeleteRank() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (id: string) => ranksApi.delete(id),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['mlm', 'ranks'] });
},
});
}
export function useEvaluateRanks() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (structureId: string) => ranksApi.evaluate(structureId),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['mlm', 'nodes'] });
},
});
}
// ============================================
// Nodes Hooks
// ============================================
export function useNodes(filters?: NodeFilters) {
return useQuery({
queryKey: ['mlm', 'nodes', filters],
queryFn: () => nodesApi.list(filters),
});
}
export function useNode(id: string) {
return useQuery({
queryKey: ['mlm', 'nodes', id],
queryFn: () => nodesApi.get(id),
enabled: !!id,
});
}
export function useCreateNode() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (data: CreateNodeDto) => nodesApi.create(data),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['mlm', 'nodes'] });
queryClient.invalidateQueries({ queryKey: ['mlm', 'my'] });
},
});
}
export function useUpdateNode() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: ({ id, data }: { id: string; data: UpdateNodeDto }) =>
nodesApi.update(id, data),
onSuccess: (_, { id }) => {
queryClient.invalidateQueries({ queryKey: ['mlm', 'nodes'] });
queryClient.invalidateQueries({ queryKey: ['mlm', 'nodes', id] });
},
});
}
export function useUpdateNodeStatus() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: ({ id, status }: { id: string; status: NodeStatus }) =>
nodesApi.updateStatus(id, { status }),
onSuccess: (_, { id }) => {
queryClient.invalidateQueries({ queryKey: ['mlm', 'nodes'] });
queryClient.invalidateQueries({ queryKey: ['mlm', 'nodes', id] });
},
});
}
export function useNodeDownline(nodeId: string, maxDepth?: number) {
return useQuery({
queryKey: ['mlm', 'nodes', nodeId, 'downline', maxDepth],
queryFn: () => nodesApi.getDownline(nodeId, maxDepth),
enabled: !!nodeId,
});
}
export function useNodeUpline(nodeId: string) {
return useQuery({
queryKey: ['mlm', 'nodes', nodeId, 'upline'],
queryFn: () => nodesApi.getUpline(nodeId),
enabled: !!nodeId,
});
}
export function useNodeTree(nodeId: string, maxDepth?: number) {
return useQuery({
queryKey: ['mlm', 'nodes', nodeId, 'tree', maxDepth],
queryFn: () => nodesApi.getTree(nodeId, maxDepth),
enabled: !!nodeId,
});
}
// ============================================
// My Network Hooks
// ============================================
export function useMyDashboard() {
return useQuery({
queryKey: ['mlm', 'my', 'dashboard'],
queryFn: () => nodesApi.getMyDashboard(),
});
}
export function useMyNetwork(maxDepth?: number) {
return useQuery({
queryKey: ['mlm', 'my', 'network', maxDepth],
queryFn: () => nodesApi.getMyNetwork(maxDepth),
});
}
export function useMyEarnings() {
return useQuery({
queryKey: ['mlm', 'my', 'earnings'],
queryFn: () => nodesApi.getMyEarnings(),
});
}
export function useMyRank() {
return useQuery({
queryKey: ['mlm', 'my', 'rank'],
queryFn: () => nodesApi.getMyRank(),
});
}
export function useGenerateInviteLink() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: () => nodesApi.generateInviteLink(),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['mlm', 'my'] });
},
});
}
// ============================================
// Commissions Hooks
// ============================================
export function useMLMCommissions(filters?: CommissionFilters) {
return useQuery({
queryKey: ['mlm', 'commissions', filters],
queryFn: () => commissionsApi.list(filters),
});
}
export function useMLMCommission(id: string) {
return useQuery({
queryKey: ['mlm', 'commissions', id],
queryFn: () => commissionsApi.get(id),
enabled: !!id,
});
}
export function useCalculateCommissions() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (data: CalculateCommissionsDto) => commissionsApi.calculate(data),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['mlm', 'commissions'] });
queryClient.invalidateQueries({ queryKey: ['mlm', 'nodes'] });
queryClient.invalidateQueries({ queryKey: ['mlm', 'my'] });
},
});
}
export function useUpdateCommissionStatus() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: ({ id, status }: { id: string; status: CommissionStatus }) =>
commissionsApi.updateStatus(id, { status }),
onSuccess: (_, { id }) => {
queryClient.invalidateQueries({ queryKey: ['mlm', 'commissions'] });
queryClient.invalidateQueries({ queryKey: ['mlm', 'commissions', id] });
},
});
}
export function useCommissionsByLevel(nodeId?: string) {
return useQuery({
queryKey: ['mlm', 'commissions', 'by-level', nodeId],
queryFn: () => commissionsApi.getByLevel(nodeId),
});
}