mirror of
https://github.com/SamyRai/turash.git
synced 2025-12-26 23:01:33 +00:00
131 lines
4.9 KiB
TypeScript
131 lines
4.9 KiB
TypeScript
import ConnectionAnalyticsSection from '@/components/analytics/ConnectionAnalyticsSection.tsx';
|
|
import ImpactBreakdownSection from '@/components/analytics/ImpactBreakdownSection.tsx';
|
|
import MatchingPerformanceSection from '@/components/analytics/MatchingPerformanceSection.tsx';
|
|
import ResourceFlowAnalyticsSection from '@/components/analytics/ResourceFlowAnalyticsSection.tsx';
|
|
import SupplyDemandSection from '@/components/analytics/SupplyDemandSection.tsx';
|
|
import MetricsGrid from '@/components/dashboard/MetricsGrid.tsx';
|
|
import { MainLayout } from '@/components/layout/MainLayout.tsx';
|
|
import PageHeader from '@/components/layout/PageHeader.tsx';
|
|
import Button from '@/components/ui/Button.tsx';
|
|
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/Card.tsx';
|
|
import { Container, Flex, Grid, Stack } from '@/components/ui/layout';
|
|
import { useAnalyticsDashboard } from '@/hooks/pages/useAnalyticsDashboard.ts';
|
|
import { useTranslation } from '@/hooks/useI18n.tsx';
|
|
import { useNavigation } from '@/hooks/useNavigation.tsx';
|
|
import { BarChart3, Building2, Target, Users } from 'lucide-react';
|
|
import { useMemo } from 'react';
|
|
|
|
const AnalyticsDashboard = () => {
|
|
const { t } = useTranslation();
|
|
const { handleBackNavigation, handleFooterNavigate } = useNavigation();
|
|
const { isLoading, analytics } = useAnalyticsDashboard();
|
|
|
|
const metricItems = useMemo(
|
|
() => [
|
|
{
|
|
icon: <Building2 className="h-5 w-5 text-current" />,
|
|
label: t('analyticsDashboard.totalOrganizations'),
|
|
value: analytics.totalOrganizations,
|
|
},
|
|
{
|
|
icon: <BarChart3 className="h-5 w-5 text-current" />,
|
|
label: t('analyticsDashboard.totalSites'),
|
|
value: analytics.totalSites,
|
|
},
|
|
{
|
|
icon: <Target className="h-5 w-5 text-current" />,
|
|
label: t('analyticsDashboard.totalMatches'),
|
|
value: analytics.totalMatches,
|
|
},
|
|
{
|
|
icon: <Users className="h-5 w-5 text-current" />,
|
|
label: t('analyticsDashboard.totalConnections'),
|
|
value: analytics.totalConnections,
|
|
},
|
|
],
|
|
[
|
|
analytics.totalConnections,
|
|
analytics.totalMatches,
|
|
analytics.totalOrganizations,
|
|
analytics.totalSites,
|
|
t,
|
|
]
|
|
);
|
|
|
|
return (
|
|
<MainLayout onNavigate={handleFooterNavigate} className="bg-muted/30">
|
|
<Container size="2xl" className="py-8 sm:py-12">
|
|
<Flex align="center" justify="between" className="mb-6">
|
|
<PageHeader
|
|
title={t('analyticsDashboard.title')}
|
|
subtitle={t('analyticsDashboard.subtitle')}
|
|
onBack={handleBackNavigation}
|
|
/>
|
|
</Flex>
|
|
|
|
<Stack spacing="2xl">
|
|
<MetricsGrid items={metricItems} cols={{ md: 2, lg: 4 }} />
|
|
|
|
<Grid cols={{ md: 2, lg: 3 }} gap="lg">
|
|
<MatchingPerformanceSection
|
|
isLoading={isLoading}
|
|
matchSuccessRate={analytics.matchSuccessRate}
|
|
avgMatchTime={analytics.avgMatchTime}
|
|
totalMatchValue={analytics.totalMatchValue}
|
|
topResourceTypes={analytics.topResourceTypes}
|
|
t={t}
|
|
/>
|
|
|
|
<ResourceFlowAnalyticsSection
|
|
flowsByType={analytics.flowsByType}
|
|
flowsBySector={analytics.flowsBySector}
|
|
avgFlowValue={analytics.avgFlowValue}
|
|
totalFlowVolume={analytics.totalFlowVolume}
|
|
t={t}
|
|
/>
|
|
|
|
<ConnectionAnalyticsSection
|
|
totalConnections={analytics.totalConnections}
|
|
activeConnections={analytics.activeConnections}
|
|
potentialConnections={analytics.potentialConnections}
|
|
connectionRate={analytics.connectionRate}
|
|
t={t}
|
|
/>
|
|
</Grid>
|
|
|
|
<ImpactBreakdownSection
|
|
isLoading={isLoading}
|
|
totalCo2Saved={analytics.totalCo2Saved}
|
|
totalEconomicValue={analytics.totalEconomicValue}
|
|
activeMatchesCount={analytics.activeMatchesCount}
|
|
environmentalBreakdown={analytics.environmentalBreakdown}
|
|
t={t}
|
|
/>
|
|
|
|
<SupplyDemandSection
|
|
topNeeds={analytics.topNeeds.map((n) => ({ label: n.item, value: n.count }))}
|
|
topOffers={analytics.topOffers.map((o) => ({ label: o.item, value: o.count }))}
|
|
marketGaps={[]}
|
|
t={t}
|
|
/>
|
|
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle>{t('analyticsDashboard.exportData')}</CardTitle>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<Flex gap="md" wrap>
|
|
<Button variant="outline">{t('analyticsDashboard.exportPDF')}</Button>
|
|
<Button variant="outline">{t('analyticsDashboard.exportCSV')}</Button>
|
|
<Button variant="outline">{t('analyticsDashboard.scheduleReports')}</Button>
|
|
</Flex>
|
|
</CardContent>
|
|
</Card>
|
|
</Stack>
|
|
</Container>
|
|
</MainLayout>
|
|
);
|
|
};
|
|
|
|
export default AnalyticsDashboard;
|