"use client"; import { keepPreviousData, useMutation, useQuery } from "@tanstack/react-query"; import { apiFetch } from "./api"; import type { DeveloperDetail, DeveloperHistoryPoint, DeveloperPortfolioObject, DeveloperTopRow, DistrictRow, MarketPulsePoint, ObjectBuilding, ObjectCheckRow, ObjectDetail, ObjectDocumentRow, ObjectFullDetail, ObjectInfraPoi, ObjectPhoto, ObjectQuartirographyRow, ObjectSaleGraphPoint, ObjectSalesAggRow, PipelineRow, PrinzipDistrictRow, PrinzipInsights, PrinzipObjectRow, QuartirographyDealsRow, QuartirographyPortfolioRow, RecommendMixInput, RecommendMixOutput, YandexListingsSummary, } from "@/types/analytics"; const BASE = "/api/v1/analytics"; export function useMarketPulse() { return useQuery({ queryKey: ["analytics", "market-pulse"], queryFn: () => apiFetch(`${BASE}/sverdl/market-pulse`), }); } export function useQuartirographyPortfolio() { return useQuery({ queryKey: ["analytics", "quartirography", "portfolio"], queryFn: () => apiFetch( `${BASE}/sverdl/quartirography?source=portfolio`, ), }); } export function useQuartirographyDeals() { return useQuery({ queryKey: ["analytics", "quartirography", "deals"], queryFn: () => apiFetch( `${BASE}/sverdl/quartirography?source=deals`, ), }); } export function usePipeline() { return useQuery({ queryKey: ["analytics", "pipeline"], queryFn: () => apiFetch(`${BASE}/sverdl/pipeline`), }); } export function useDistricts() { return useQuery({ queryKey: ["analytics", "districts"], queryFn: () => apiFetch(`${BASE}/sverdl/districts`), }); } export function useYandexListings() { return useQuery({ queryKey: ["analytics", "yandex"], queryFn: () => apiFetch(`${BASE}/sverdl/yandex-listings`), }); } export function useTopDevelopers(limit = 15) { return useQuery({ queryKey: ["analytics", "top-devs", limit], queryFn: () => apiFetch(`${BASE}/developers/top?limit=${limit}`), }); } export function useDeveloperDetail(developerId: string) { return useQuery({ queryKey: ["analytics", "dev", developerId], queryFn: () => apiFetch(`${BASE}/developers/${developerId}`), enabled: !!developerId, }); } export function useDeveloperHistory(developerIds: string[]) { const idsParam = developerIds.join(","); return useQuery({ queryKey: ["analytics", "dev-history", idsParam], queryFn: () => apiFetch( `${BASE}/developers/history?ids=${encodeURIComponent(idsParam)}`, ), enabled: developerIds.length > 0, }); } export function useDeveloperPortfolio(developerId: string) { return useQuery({ queryKey: ["analytics", "dev-portfolio", developerId], queryFn: () => apiFetch( `${BASE}/developers/${developerId}/portfolio`, ), enabled: !!developerId, }); } export function usePrinzipInsights() { return useQuery({ queryKey: ["analytics", "prinzip-insights"], queryFn: () => apiFetch(`${BASE}/prinzip/insights`), staleTime: Infinity, }); } export function usePrinzipDistricts() { return useQuery({ queryKey: ["analytics", "prinzip-districts"], queryFn: () => apiFetch(`${BASE}/prinzip/districts`), }); } export function usePrinzipObjects() { return useQuery({ queryKey: ["analytics", "prinzip-objects"], queryFn: () => apiFetch(`${BASE}/prinzip/objects`), }); } // Funnel hooks moved to /admin/leads page (CRM data is admin-only). // ── Per-object drill-in ───────────────────────────────────────────────────── export function useObjectDetail(objId: number | string) { return useQuery({ queryKey: ["analytics", "object", objId], queryFn: () => apiFetch(`${BASE}/object/${objId}`), enabled: !!objId, }); } export function useObjectSaleGraph(objId: number | string, type?: string) { return useQuery({ queryKey: ["analytics", "object-sale-graph", objId, type], queryFn: () => { const q = type ? `?type=${type}` : ""; return apiFetch( `${BASE}/object/${objId}/sale_graph${q}`, ); }, enabled: !!objId, }); } export function useObjectSalesAgg(objId: number | string) { return useQuery({ queryKey: ["analytics", "object-sales-agg", objId], queryFn: () => apiFetch(`${BASE}/object/${objId}/sales_agg`), enabled: !!objId, }); } export function useObjectInfrastructure( objId: number | string, opts?: { category?: string; max_distance?: number }, ) { return useQuery({ queryKey: [ "analytics", "object-infra", objId, opts?.category, opts?.max_distance, ], queryFn: () => { const params = new URLSearchParams(); if (opts?.category) params.set("category", opts.category); if (opts?.max_distance != null) params.set("max_distance", String(opts.max_distance)); const qs = params.toString(); return apiFetch( `${BASE}/object/${objId}/infrastructure${qs ? "?" + qs : ""}`, ); }, enabled: !!objId, placeholderData: keepPreviousData, }); } export function useObjectPhotos(objId: number | string, limit = 100) { return useQuery({ queryKey: ["analytics", "object-photos", objId, limit], queryFn: () => apiFetch(`${BASE}/object/${objId}/photos?limit=${limit}`), enabled: !!objId, }); } export function useObjectBuildings(objId: number | string) { return useQuery({ queryKey: ["analytics", "object-buildings", objId], queryFn: () => apiFetch(`${BASE}/object/${objId}/buildings`), enabled: !!objId, }); } export function useObjectFullDetail(objId: number | string) { return useQuery({ queryKey: ["analytics", "object-full", objId], queryFn: () => apiFetch(`${BASE}/object/${objId}/full`), enabled: !!objId, }); } export function useObjectQuartirography(objId: number | string) { return useQuery({ queryKey: ["analytics", "object-quartirography", objId], queryFn: () => apiFetch( `${BASE}/object/${objId}/quartirography`, ), enabled: !!objId, }); } export function useObjectChecks(objId: number | string) { return useQuery({ queryKey: ["analytics", "object-checks", objId], queryFn: () => apiFetch(`${BASE}/object/${objId}/checks`), enabled: !!objId, }); } export function useObjectDocuments(objId: number | string) { return useQuery({ queryKey: ["analytics", "object-documents", objId], queryFn: () => apiFetch(`${BASE}/object/${objId}/documents`), enabled: !!objId, }); } // ── Recommender (Уровень 1) ───────────────────────────────────────────────── export function useRecommendMix() { return useMutation({ mutationFn: (input: RecommendMixInput) => apiFetch(`${BASE}/recommend/mix`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(input), }), }); }