turash/bugulma/frontend/hooks/api/useProposalsAPI.ts
Damir Mukimov 6347f42e20
Consolidate repositories: Remove nested frontend .git and merge into main repository
- Remove nested git repository from bugulma/frontend/.git
- Add all frontend files to main repository tracking
- Convert from separate frontend/backend repos to unified monorepo
- Preserve all frontend code and development history as tracked files
- Eliminate nested repository complexity for simpler development workflow

This creates a proper monorepo structure with frontend and backend
coexisting in the same repository for easier development and deployment.
2025-11-25 06:02:57 +01:00

104 lines
2.8 KiB
TypeScript

import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import * as proposalsApi from '@/services/proposals-api.ts';
/**
* Get all proposals with optional filters
* Returns safe default structure to prevent freezing on empty/null responses
*/
export function useProposals(params?: {
organization_id?: string;
status?: 'pending' | 'accepted' | 'rejected';
type?: 'incoming' | 'outgoing';
}) {
return useQuery({
queryKey: ['proposals', params],
queryFn: async () => {
try {
const data = await proposalsApi.getProposals(params);
// Ensure we always return a valid structure
return {
proposals: Array.isArray(data?.proposals) ? data.proposals : [],
...data,
};
} catch {
// Return safe default on error
return { proposals: [] };
}
},
// Return safe default while loading
placeholderData: { proposals: [] },
});
}
/**
* Get proposal by ID
* Returns undefined immediately to prevent blocking render
*/
export function useProposal(id: string | undefined) {
return useQuery({
queryKey: ['proposals', id],
queryFn: () => proposalsApi.getProposalById(id!),
enabled: !!id,
placeholderData: undefined, // Render immediately, data loads async
});
}
/**
* Get proposals for an organization
* Returns safe default structure to prevent freezing on empty/null responses
*/
export function useProposalsForOrganization(
orgId: string | undefined,
type?: 'incoming' | 'outgoing'
) {
return useQuery({
queryKey: ['proposals', 'organization', orgId, type],
queryFn: async () => {
try {
const data = await proposalsApi.getProposalsForOrganization(orgId!, type);
// Ensure we always return a valid structure
return {
incoming: Array.isArray(data?.incoming) ? data.incoming : [],
outgoing: Array.isArray(data?.outgoing) ? data.outgoing : [],
...data,
};
} catch {
// Return safe default on error
return { incoming: [], outgoing: [] };
}
},
enabled: !!orgId,
// Return safe default while loading
placeholderData: { incoming: [], outgoing: [] },
});
}
/**
* Create a new proposal
*/
export function useCreateProposal() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: proposalsApi.createProposal,
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['proposals'] });
},
});
}
/**
* Update proposal status
*/
export function useUpdateProposalStatus() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: ({ id, status }: { id: string; status: 'pending' | 'accepted' | 'rejected' }) =>
proposalsApi.updateProposalStatus(id, { status }),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['proposals'] });
},
});
}