// ============================================================ // CRM – React Query Hooks // ============================================================ import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; import { contactsApi, dealsApi, pipelinesApi, activitiesApi, companiesApi, lexwareContactsApi, lexwareVouchersApi, } from './api'; import type { ContactsQueryParams, DealsQueryParams, ActivitiesQueryParams, CreateContactPayload, UpdateContactPayload, CreateDealPayload, UpdateDealPayload, CreatePipelinePayload, UpdatePipelinePayload, CreateStagePayload, UpdateStagePayload, CreateActivityPayload, UpdateActivityPayload, CompaniesQueryParams, CreateCompanyPayload, UpdateCompanyPayload, LexwareContactSearchParams, LexwareVouchersQueryParams, } from './types'; // --- Query Key Factory --- export const crmKeys = { contacts: { all: ['crm', 'contacts'] as const, list: (params: ContactsQueryParams) => ['crm', 'contacts', 'list', params] as const, detail: (id: string) => ['crm', 'contacts', 'detail', id] as const, }, deals: { all: ['crm', 'deals'] as const, list: (params: DealsQueryParams) => ['crm', 'deals', 'list', params] as const, detail: (id: string) => ['crm', 'deals', 'detail', id] as const, }, pipelines: { all: ['crm', 'pipelines'] as const, list: () => ['crm', 'pipelines', 'list'] as const, detail: (id: string) => ['crm', 'pipelines', 'detail', id] as const, }, activities: { all: ['crm', 'activities'] as const, list: (params: ActivitiesQueryParams) => ['crm', 'activities', 'list', params] as const, detail: (id: string) => ['crm', 'activities', 'detail', id] as const, }, companies: { all: ['crm', 'companies'] as const, list: (params: CompaniesQueryParams) => ['crm', 'companies', 'list', params] as const, detail: (id: string) => ['crm', 'companies', 'detail', id] as const, }, lexware: { all: ['crm', 'lexware'] as const, contactSearch: (params: LexwareContactSearchParams) => ['crm', 'lexware', 'contacts', 'search', params] as const, vouchersCompany: (companyId: string, params?: LexwareVouchersQueryParams) => ['crm', 'lexware', 'vouchers', 'company', companyId, params] as const, vouchersContact: (contactId: string, params?: LexwareVouchersQueryParams) => ['crm', 'lexware', 'vouchers', 'contact', contactId, params] as const, vouchersDeal: (dealId: string) => ['crm', 'lexware', 'vouchers', 'deal', dealId] as const, }, }; // ============================================================ // Contacts // ============================================================ export function useContacts(params: ContactsQueryParams) { return useQuery({ queryKey: crmKeys.contacts.list(params), queryFn: () => contactsApi.list(params), }); } export function useContact(id: string) { return useQuery({ queryKey: crmKeys.contacts.detail(id), queryFn: () => contactsApi.getById(id), enabled: !!id, }); } export function useCreateContact() { const qc = useQueryClient(); return useMutation({ mutationFn: (data: CreateContactPayload) => contactsApi.create(data), onSuccess: () => { qc.invalidateQueries({ queryKey: crmKeys.contacts.all }); qc.invalidateQueries({ queryKey: crmKeys.companies.all }); }, }); } export function useUpdateContact() { const qc = useQueryClient(); return useMutation({ mutationFn: ({ id, data }: { id: string; data: UpdateContactPayload }) => contactsApi.update(id, data), onSuccess: () => { qc.invalidateQueries({ queryKey: crmKeys.contacts.all }); qc.invalidateQueries({ queryKey: crmKeys.companies.all }); }, }); } export function useDeleteContact() { const qc = useQueryClient(); return useMutation({ mutationFn: (id: string) => contactsApi.delete(id), onSuccess: () => { qc.invalidateQueries({ queryKey: crmKeys.contacts.all }); qc.invalidateQueries({ queryKey: crmKeys.companies.all }); }, }); } // ============================================================ // Deals // ============================================================ export function useDeals(params: DealsQueryParams) { return useQuery({ queryKey: crmKeys.deals.list(params), queryFn: () => dealsApi.list(params), }); } export function useDeal(id: string) { return useQuery({ queryKey: crmKeys.deals.detail(id), queryFn: () => dealsApi.getById(id), enabled: !!id, }); } export function useCreateDeal() { const qc = useQueryClient(); return useMutation({ mutationFn: (data: CreateDealPayload) => dealsApi.create(data), onSuccess: () => { qc.invalidateQueries({ queryKey: crmKeys.deals.all }); qc.invalidateQueries({ queryKey: crmKeys.companies.all }); }, }); } export function useUpdateDeal() { const qc = useQueryClient(); return useMutation({ mutationFn: ({ id, data }: { id: string; data: UpdateDealPayload }) => dealsApi.update(id, data), onSuccess: () => { qc.invalidateQueries({ queryKey: crmKeys.deals.all }); qc.invalidateQueries({ queryKey: crmKeys.companies.all }); }, }); } export function useDeleteDeal() { const qc = useQueryClient(); return useMutation({ mutationFn: (id: string) => dealsApi.delete(id), onSuccess: () => { qc.invalidateQueries({ queryKey: crmKeys.deals.all }); qc.invalidateQueries({ queryKey: crmKeys.companies.all }); }, }); } // ============================================================ // Pipelines // ============================================================ export function usePipelines() { return useQuery({ queryKey: crmKeys.pipelines.list(), queryFn: () => pipelinesApi.list(), staleTime: 10 * 60 * 1000, // Pipelines aendern sich selten }); } export function usePipeline(id: string) { return useQuery({ queryKey: crmKeys.pipelines.detail(id), queryFn: () => pipelinesApi.getById(id), enabled: !!id, }); } export function useCreatePipeline() { const qc = useQueryClient(); return useMutation({ mutationFn: (data: CreatePipelinePayload) => pipelinesApi.create(data), onSuccess: () => { qc.invalidateQueries({ queryKey: crmKeys.pipelines.all }); }, }); } export function useUpdatePipeline() { const qc = useQueryClient(); return useMutation({ mutationFn: ({ id, data, }: { id: string; data: UpdatePipelinePayload; }) => pipelinesApi.update(id, data), onSuccess: () => { qc.invalidateQueries({ queryKey: crmKeys.pipelines.all }); }, }); } export function useDeletePipeline() { const qc = useQueryClient(); return useMutation({ mutationFn: (id: string) => pipelinesApi.delete(id), onSuccess: () => { qc.invalidateQueries({ queryKey: crmKeys.pipelines.all }); }, }); } export function useUpdateStage() { const qc = useQueryClient(); return useMutation({ mutationFn: ({ pipelineId, stageId, data, }: { pipelineId: string; stageId: string; data: UpdateStagePayload; }) => pipelinesApi.updateStage(pipelineId, stageId, data), onSuccess: () => { qc.invalidateQueries({ queryKey: crmKeys.pipelines.all }); }, }); } export function useAddStage() { const qc = useQueryClient(); return useMutation({ mutationFn: ({ pipelineId, data, }: { pipelineId: string; data: CreateStagePayload; }) => pipelinesApi.addStage(pipelineId, data), onSuccess: () => { qc.invalidateQueries({ queryKey: crmKeys.pipelines.all }); }, }); } export function useRemoveStage() { const qc = useQueryClient(); return useMutation({ mutationFn: ({ pipelineId, stageId, }: { pipelineId: string; stageId: string; }) => pipelinesApi.removeStage(pipelineId, stageId), onSuccess: () => { qc.invalidateQueries({ queryKey: crmKeys.pipelines.all }); }, }); } // ============================================================ // Activities // ============================================================ export function useActivities(params: ActivitiesQueryParams) { return useQuery({ queryKey: crmKeys.activities.list(params), queryFn: () => activitiesApi.list(params), }); } export function useCreateActivity() { const qc = useQueryClient(); return useMutation({ mutationFn: (data: CreateActivityPayload) => activitiesApi.create(data), onSuccess: () => { qc.invalidateQueries({ queryKey: crmKeys.activities.all }); qc.invalidateQueries({ queryKey: crmKeys.contacts.all }); }, }); } export function useUpdateActivity() { const qc = useQueryClient(); return useMutation({ mutationFn: ({ id, data, }: { id: string; data: UpdateActivityPayload; }) => activitiesApi.update(id, data), onSuccess: () => { qc.invalidateQueries({ queryKey: crmKeys.activities.all }); qc.invalidateQueries({ queryKey: crmKeys.contacts.all }); }, }); } export function useDeleteActivity() { const qc = useQueryClient(); return useMutation({ mutationFn: (id: string) => activitiesApi.delete(id), onSuccess: () => { qc.invalidateQueries({ queryKey: crmKeys.activities.all }); qc.invalidateQueries({ queryKey: crmKeys.contacts.all }); }, }); } // ============================================================ // Companies // ============================================================ export function useCompanies(params: CompaniesQueryParams) { return useQuery({ queryKey: crmKeys.companies.list(params), queryFn: () => companiesApi.list(params), }); } export function useCompany(id: string) { return useQuery({ queryKey: crmKeys.companies.detail(id), queryFn: () => companiesApi.getById(id), enabled: !!id, }); } export function useCreateCompany() { const qc = useQueryClient(); return useMutation({ mutationFn: (data: CreateCompanyPayload) => companiesApi.create(data), onSuccess: () => { qc.invalidateQueries({ queryKey: crmKeys.companies.all }); }, }); } export function useUpdateCompany() { const qc = useQueryClient(); return useMutation({ mutationFn: ({ id, data }: { id: string; data: UpdateCompanyPayload }) => companiesApi.update(id, data), onSuccess: () => { qc.invalidateQueries({ queryKey: crmKeys.companies.all }); }, }); } export function useDeleteCompany() { const qc = useQueryClient(); return useMutation({ mutationFn: (id: string) => companiesApi.delete(id), onSuccess: () => { qc.invalidateQueries({ queryKey: crmKeys.companies.all }); }, }); } // ============================================================ // Lexware Office — Contacts // ============================================================ export function useLexwareContactSearch( params: LexwareContactSearchParams, enabled = true, ) { return useQuery({ queryKey: crmKeys.lexware.contactSearch(params), queryFn: () => lexwareContactsApi.search(params), enabled: enabled && !!(params.name || params.email), }); } export function useLinkLexwareCompany() { const qc = useQueryClient(); return useMutation({ mutationFn: (data: { lexwareContactId: string; companyId: string }) => lexwareContactsApi.linkCompany(data), onSuccess: () => { qc.invalidateQueries({ queryKey: crmKeys.companies.all }); qc.invalidateQueries({ queryKey: crmKeys.lexware.all }); }, }); } export function useLinkLexwareContact() { const qc = useQueryClient(); return useMutation({ mutationFn: (data: { lexwareContactId: string; contactId: string }) => lexwareContactsApi.linkContact(data), onSuccess: () => { qc.invalidateQueries({ queryKey: crmKeys.contacts.all }); qc.invalidateQueries({ queryKey: crmKeys.lexware.all }); }, }); } export function useUnlinkLexwareCompany() { const qc = useQueryClient(); return useMutation({ mutationFn: (companyId: string) => lexwareContactsApi.unlinkCompany(companyId), onSuccess: () => { qc.invalidateQueries({ queryKey: crmKeys.companies.all }); qc.invalidateQueries({ queryKey: crmKeys.lexware.all }); }, }); } export function useUnlinkLexwareContact() { const qc = useQueryClient(); return useMutation({ mutationFn: (contactId: string) => lexwareContactsApi.unlinkContact(contactId), onSuccess: () => { qc.invalidateQueries({ queryKey: crmKeys.contacts.all }); qc.invalidateQueries({ queryKey: crmKeys.lexware.all }); }, }); } export function usePushToLexware() { const qc = useQueryClient(); return useMutation({ mutationFn: ({ entityType, entityId, }: { entityType: 'company' | 'contact'; entityId: string; }) => lexwareContactsApi.push(entityType, entityId), onSuccess: () => { qc.invalidateQueries({ queryKey: crmKeys.companies.all }); qc.invalidateQueries({ queryKey: crmKeys.contacts.all }); }, }); } export function useSyncFromLexware() { const qc = useQueryClient(); return useMutation({ mutationFn: ({ entityType, entityId, }: { entityType: 'company' | 'contact'; entityId: string; }) => lexwareContactsApi.sync(entityType, entityId), onSuccess: () => { qc.invalidateQueries({ queryKey: crmKeys.companies.all }); qc.invalidateQueries({ queryKey: crmKeys.contacts.all }); }, }); } export function useImportLexwareAsCompany() { const qc = useQueryClient(); return useMutation({ mutationFn: (data: { lexwareContactId: string }) => lexwareContactsApi.importCompany(data), onSuccess: () => { qc.invalidateQueries({ queryKey: crmKeys.companies.all }); qc.invalidateQueries({ queryKey: crmKeys.lexware.all }); }, }); } export function useImportLexwareAsContact() { const qc = useQueryClient(); return useMutation({ mutationFn: (data: { lexwareContactId: string }) => lexwareContactsApi.importContact(data), onSuccess: () => { qc.invalidateQueries({ queryKey: crmKeys.contacts.all }); qc.invalidateQueries({ queryKey: crmKeys.lexware.all }); }, }); } // ============================================================ // Lexware Office — Vouchers // ============================================================ export function useCompanyVouchers( companyId: string, params?: LexwareVouchersQueryParams, ) { return useQuery({ queryKey: crmKeys.lexware.vouchersCompany(companyId, params), queryFn: () => lexwareVouchersApi.getForCompany(companyId, params), enabled: !!companyId, }); } export function useContactVouchers( contactId: string, params?: LexwareVouchersQueryParams, ) { return useQuery({ queryKey: crmKeys.lexware.vouchersContact(contactId, params), queryFn: () => lexwareVouchersApi.getForContact(contactId, params), enabled: !!contactId, }); } export function useDealVouchers(dealId: string) { return useQuery({ queryKey: crmKeys.lexware.vouchersDeal(dealId), queryFn: () => lexwareVouchersApi.getForDeal(dealId), enabled: !!dealId, }); } export function useLinkVoucherToDeal() { const qc = useQueryClient(); return useMutation({ mutationFn: ({ dealId, voucherId }: { dealId: string; voucherId: string }) => lexwareVouchersApi.linkToDeal(dealId, voucherId), onSuccess: () => { qc.invalidateQueries({ queryKey: crmKeys.lexware.all }); qc.invalidateQueries({ queryKey: crmKeys.deals.all }); }, }); } export function useUnlinkVoucherFromDeal() { const qc = useQueryClient(); return useMutation({ mutationFn: ({ dealId, voucherId }: { dealId: string; voucherId: string }) => lexwareVouchersApi.unlinkFromDeal(dealId, voucherId), onSuccess: () => { qc.invalidateQueries({ queryKey: crmKeys.lexware.all }); qc.invalidateQueries({ queryKey: crmKeys.deals.all }); }, }); } export function useRefreshCompanyVouchers() { const qc = useQueryClient(); return useMutation({ mutationFn: (companyId: string) => lexwareVouchersApi.refreshCompany(companyId), onSuccess: () => { qc.invalidateQueries({ queryKey: crmKeys.lexware.all }); }, }); } export function useRefreshContactVouchers() { const qc = useQueryClient(); return useMutation({ mutationFn: (contactId: string) => lexwareVouchersApi.refreshContact(contactId), onSuccess: () => { qc.invalidateQueries({ queryKey: crmKeys.lexware.all }); }, }); }