mirror of
https://github.com/SamyRai/turash.git
synced 2025-12-26 23:01:33 +00:00
139 lines
5.0 KiB
TypeScript
139 lines
5.0 KiB
TypeScript
import {
|
|
useConnectionStatistics,
|
|
useImpactMetrics,
|
|
useMatchingStatistics,
|
|
usePlatformStatistics,
|
|
useResourceFlowStatistics,
|
|
useSupplyDemandAnalysis,
|
|
} from '@/hooks/api/useAnalyticsAPI.ts';
|
|
import type {
|
|
ConnectionStatistics,
|
|
ImpactMetrics,
|
|
MatchingStatistics,
|
|
PlatformStatistics,
|
|
ResourceFlowStatistics,
|
|
SupplyDemandAnalysis,
|
|
} from '@/services/analytics-api.ts';
|
|
import { useMemo } from 'react';
|
|
|
|
export type AnalyticsDashboardData = {
|
|
totalOrganizations: number;
|
|
totalSites: number;
|
|
totalResourceFlows: number;
|
|
totalMatches: number;
|
|
|
|
matchSuccessRate: number;
|
|
avgMatchTime: number;
|
|
totalMatchValue: number;
|
|
topResourceTypes: Array<{ type: string; count: number }>;
|
|
|
|
flowsByType: Record<string, number>;
|
|
flowsBySector: Record<string, number>;
|
|
avgFlowValue: number;
|
|
totalFlowVolume: number;
|
|
|
|
totalConnections: number;
|
|
activeConnections: number;
|
|
potentialConnections: number;
|
|
connectionRate: number;
|
|
|
|
totalCo2Saved: number;
|
|
totalEconomicValue: number;
|
|
activeMatchesCount: number;
|
|
environmentalBreakdown: Record<string, unknown>;
|
|
|
|
topNeeds: Array<{ item: string; count: number }>;
|
|
topOffers: Array<{ item: string; count: number }>;
|
|
};
|
|
|
|
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
return typeof value === 'object' && value !== null;
|
|
}
|
|
|
|
export function useAnalyticsDashboard() {
|
|
const { data: platformStats, isLoading: isLoadingPlatform } = usePlatformStatistics();
|
|
const { data: matchingStats, isLoading: isLoadingMatching } = useMatchingStatistics();
|
|
const { data: resourceFlowStats, isLoading: isLoadingResourceFlow } = useResourceFlowStatistics();
|
|
const { data: impactMetrics, isLoading: isLoadingImpact } = useImpactMetrics();
|
|
const { data: connectionStats, isLoading: isLoadingConnections } = useConnectionStatistics();
|
|
const { data: supplyDemand, isLoading: isLoadingSupplyDemand } = useSupplyDemandAnalysis();
|
|
|
|
const isLoading =
|
|
isLoadingPlatform ||
|
|
isLoadingMatching ||
|
|
isLoadingResourceFlow ||
|
|
isLoadingImpact ||
|
|
isLoadingConnections ||
|
|
isLoadingSupplyDemand;
|
|
|
|
const analytics: AnalyticsDashboardData = useMemo(() => {
|
|
const platform: Partial<PlatformStatistics> = platformStats ?? {};
|
|
const matching: Partial<MatchingStatistics> = matchingStats ?? {};
|
|
const resourceFlow: Partial<ResourceFlowStatistics> = resourceFlowStats ?? {};
|
|
const impact: Partial<ImpactMetrics> = impactMetrics ?? {};
|
|
const connections: Partial<ConnectionStatistics> = connectionStats ?? {};
|
|
const supplyDemandData: Partial<SupplyDemandAnalysis> = supplyDemand ?? {};
|
|
|
|
const totalConnections = Number(connections.total_connections || 0);
|
|
const activeConnections = Number(connections.active_connections || 0);
|
|
const potentialConnections = Number(connections.potential_connections || 0);
|
|
const connectionRate = totalConnections > 0 ? activeConnections / totalConnections : 0;
|
|
|
|
const topResourceTypesRaw = matching.top_resource_types ?? [];
|
|
const topResourceTypes = Array.isArray(topResourceTypesRaw)
|
|
? topResourceTypesRaw
|
|
.map((it: unknown) => {
|
|
if (typeof it === 'string') return { type: it, count: 1 };
|
|
if (isRecord(it)) {
|
|
const type = typeof it.type === 'string' ? it.type : '';
|
|
const count = typeof it.count === 'number' ? it.count : 1;
|
|
return { type, count };
|
|
}
|
|
return { type: '', count: 1 };
|
|
})
|
|
.filter((x) => x.type)
|
|
: [];
|
|
|
|
return {
|
|
totalOrganizations: Number(platform.total_organizations || 0),
|
|
totalSites: Number(platform.total_sites || 0),
|
|
totalResourceFlows: Number(platform.total_resource_flows || 0),
|
|
totalMatches: Number(platform.total_matches || 0),
|
|
|
|
matchSuccessRate: Number(matching.match_success_rate || 0),
|
|
avgMatchTime: Number(matching.avg_match_time_days || 0),
|
|
totalMatchValue: Number(matching.total_match_value || 0),
|
|
topResourceTypes,
|
|
|
|
flowsByType: (resourceFlow.flows_by_type || {}) as Record<string, number>,
|
|
flowsBySector: (resourceFlow.flows_by_sector || {}) as Record<string, number>,
|
|
avgFlowValue: Number(resourceFlow.avg_flow_value || 0),
|
|
totalFlowVolume: Number(resourceFlow.total_flow_volume || 0),
|
|
|
|
totalConnections,
|
|
activeConnections,
|
|
potentialConnections,
|
|
connectionRate,
|
|
|
|
totalCo2Saved: Number(impact.total_co2_savings_tonnes || 0),
|
|
totalEconomicValue: Number(impact.total_economic_value_eur || 0),
|
|
activeMatchesCount: Number(impact.active_matches_count || 0),
|
|
environmentalBreakdown: isRecord(impact.environmental_breakdown)
|
|
? impact.environmental_breakdown
|
|
: {},
|
|
|
|
topNeeds: (supplyDemandData.top_needs || []) as Array<{ item: string; count: number }>,
|
|
topOffers: (supplyDemandData.top_offers || []) as Array<{ item: string; count: number }>,
|
|
};
|
|
}, [
|
|
platformStats,
|
|
matchingStats,
|
|
resourceFlowStats,
|
|
impactMetrics,
|
|
connectionStats,
|
|
supplyDemand,
|
|
]);
|
|
|
|
return { isLoading, analytics };
|
|
}
|