95 lines
3.0 KiB
TypeScript
95 lines
3.0 KiB
TypeScript
import React, { useState } from 'react';
|
||
import {
|
||
IntelligenceItem,
|
||
University1415Dimension,
|
||
JobEntity,
|
||
SkillEntity
|
||
} from '../types/futures';
|
||
import { StrategicGraph } from '../components/visual/StrategicGraph';
|
||
import { ImpactNetwork } from '../components/visual/ImpactNetwork';
|
||
import { PageHeader } from '../components/common/PageHeader';
|
||
|
||
import { Card, CardContent } from '@/components/ui/card';
|
||
import { Tabs, TabsList, TabsTrigger } from '@/components/ui/tabs';
|
||
import { Share2, Route } from 'lucide-react';
|
||
|
||
interface StrategicNetworkPageProps {
|
||
items: IntelligenceItem[];
|
||
dimensions: University1415Dimension[];
|
||
jobs: JobEntity[];
|
||
skills: SkillEntity[];
|
||
onSelectItem: (item: IntelligenceItem) => void;
|
||
onSelectDimension: (dim: University1415Dimension) => void;
|
||
}
|
||
|
||
export const StrategicNetworkPage: React.FC<StrategicNetworkPageProps> = ({
|
||
items,
|
||
dimensions,
|
||
jobs,
|
||
skills,
|
||
onSelectItem,
|
||
onSelectDimension
|
||
}) => {
|
||
const [view, setView] = useState<'network' | 'chain'>('network');
|
||
|
||
const handleSelectEntity = (type: string, id: string) => {
|
||
if (type === 'item') {
|
||
const found = items.find((i) => i.id === id);
|
||
if (found) onSelectItem(found);
|
||
} else if (type === 'dimension') {
|
||
const found = dimensions.find((d) => d.id === id);
|
||
if (found) onSelectDimension(found);
|
||
}
|
||
};
|
||
|
||
return (
|
||
<div className="animate-in fade-in duration-300">
|
||
<PageHeader
|
||
title="شبکه روابط"
|
||
description="مسیر اثر هر پیشران: از فناوری یا سیگنال بیرونی تا مهارت، شغل و شکاف قابلیت دانشگاه."
|
||
actions={
|
||
<Tabs value={view} onValueChange={(v) => setView(v as typeof view)}>
|
||
<TabsList className="h-9">
|
||
<TabsTrigger value="network" className="gap-1.5">
|
||
<Share2 className="size-3.5" />
|
||
<span className="hidden sm:inline">شبکه</span>
|
||
</TabsTrigger>
|
||
<TabsTrigger value="chain" className="gap-1.5">
|
||
<Route className="size-3.5" />
|
||
<span className="hidden sm:inline">زنجیره</span>
|
||
</TabsTrigger>
|
||
</TabsList>
|
||
</Tabs>
|
||
}
|
||
/>
|
||
|
||
{view === 'network' && (
|
||
<Card data-card className="animate-in fade-in duration-300">
|
||
<CardContent className="p-3 sm:p-6">
|
||
<ImpactNetwork
|
||
items={items}
|
||
dimensions={dimensions}
|
||
jobs={jobs}
|
||
skills={skills}
|
||
onOpenItem={onSelectItem}
|
||
onOpenDimension={onSelectDimension}
|
||
/>
|
||
</CardContent>
|
||
</Card>
|
||
)}
|
||
|
||
{view === 'chain' && (
|
||
<div className="animate-in fade-in duration-300">
|
||
<StrategicGraph
|
||
items={items}
|
||
dimensions={dimensions}
|
||
jobs={jobs}
|
||
skills={skills}
|
||
onSelectEntity={handleSelectEntity}
|
||
/>
|
||
</div>
|
||
)}
|
||
</div>
|
||
);
|
||
};
|