turash/bugulma/frontend/components/organization/OrganizationContent.tsx

156 lines
5.2 KiB
TypeScript

import MatchesList from '@/components/matches/MatchesList.tsx';
import HistoricalContextCard from '@/components/organization/HistoricalContextCard.tsx';
import { NetworkGraph } from '@/components/organization/NetworkGraph.tsx';
import OrganizationDetailsGrid from '@/components/organization/OrganizationDetailsGrid.tsx';
import OrganizationHeader from '@/components/organization/OrganizationHeader.tsx';
import PartnershipHub from '@/components/organization/PartnershipHub.tsx';
import ProductsServicesList from '@/components/organization/ProductsServicesList.tsx';
import ResourceFlowList from '@/components/resource-flow/ResourceFlowList.tsx';
import Button from '@/components/ui/Button.tsx';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/Card.tsx';
import { Heading, Text } from '@/components/ui/Typography.tsx';
import { useTranslation } from '@/hooks/useI18n.tsx';
import type {
HistoricalLandmark,
Organization,
SymbiosisMatch,
WebIntelligenceResult,
} from '@/types.ts';
import React, { useCallback, useMemo, useState } from 'react';
import { useNavigate } from 'react-router-dom';
interface SymbiosisState {
symbiosisResult: SymbiosisMatch[] | null;
isAnalyzing: boolean;
analysisError: string | null;
webIntelResult: WebIntelligenceResult | null;
isFetchingWebIntel: boolean;
webIntelError: string | null;
}
interface OrganizationContentProps {
organization: Organization;
relatedLandmark: HistoricalLandmark | null;
symbiosisState: SymbiosisState;
handleUpdateOrganization: (updatedOrg: Organization) => void;
handleMapNavigation: () => void;
handleSelectOrg: (org: Organization) => void;
handleAnalyzeSymbiosis: () => void;
handleFetchWebIntelligence: () => void;
}
const OrganizationContent: React.FC<OrganizationContentProps> = ({
organization,
relatedLandmark,
symbiosisState,
handleUpdateOrganization,
handleMapNavigation,
handleSelectOrg,
handleAnalyzeSymbiosis,
handleFetchWebIntelligence,
}) => {
const { t } = useTranslation();
const navigate = useNavigate();
const [selectedResourceId, setSelectedResourceId] = useState<string | null>(null);
const handleViewMatches = useCallback((resourceId: string) => {
setSelectedResourceId(resourceId);
}, []);
const handleCloseMatches = useCallback(() => {
setSelectedResourceId(null);
}, []);
const handleNetworkNodeClick = useCallback(
(nodeId: string, nodeType: string) => {
if (nodeType === 'Organization' && nodeId !== organization.ID) {
// Navigate to the clicked organization
navigate(`/organization/${nodeId}`);
}
// For Sites, ResourceFlows, etc., we could add more navigation logic
},
[navigate, organization.ID]
);
// Memoize the ai object to prevent PartnershipHub re-renders
const aiProps = useMemo(
() => ({
symbiosisResult: symbiosisState.symbiosisResult,
isAnalyzing: symbiosisState.isAnalyzing,
analysisError: symbiosisState.analysisError,
handleAnalyzeSymbiosis,
webIntelResult: symbiosisState.webIntelResult,
isFetchingWebIntel: symbiosisState.isFetchingWebIntel,
webIntelError: symbiosisState.webIntelError,
handleFetchWebIntelligence,
}),
[
symbiosisState.symbiosisResult,
symbiosisState.isAnalyzing,
symbiosisState.analysisError,
handleAnalyzeSymbiosis,
symbiosisState.webIntelResult,
symbiosisState.isFetchingWebIntel,
symbiosisState.webIntelError,
handleFetchWebIntelligence,
]
);
return (
<div className="space-y-8 lg:col-span-2">
<OrganizationHeader
organization={organization}
onUpdateOrganization={handleUpdateOrganization}
/>
{relatedLandmark && (
<HistoricalContextCard landmark={relatedLandmark} onNavigate={handleMapNavigation} />
)}
<Card>
<CardHeader>
<CardTitle>{t('organizationPage.description')}</CardTitle>
</CardHeader>
<CardContent className="prose max-w-none">
<Text>{organization.Description}</Text>
</CardContent>
</Card>
<OrganizationDetailsGrid organization={organization} />
{/* Network Graph - Visual representation of connections */}
<NetworkGraph
organizationId={organization.ID}
organizationName={organization.Name}
depth={2}
onNodeClick={handleNetworkNodeClick}
/>
<ResourceFlowList organizationId={organization.ID} onViewMatches={handleViewMatches} />
<ProductsServicesList organizationId={organization.ID} />
{selectedResourceId && (
<div className="space-y-4">
<div className="flex items-center justify-between">
<Heading level="h3" tKey="matches.title" />
<Button
variant="ghost"
size="sm"
onClick={handleCloseMatches}
className="text-muted-foreground"
>
{t('common.close')}
</Button>
</div>
<MatchesList resourceId={selectedResourceId} />
</div>
)}
<PartnershipHub organization={organization} onSelectOrg={handleSelectOrg} ai={aiProps} />
</div>
);
};
export default React.memo(OrganizationContent);