import { useEffect, useReducer, useState } from "react"; import { Bar, BarChart, CartesianGrid, Cell, LabelList, ResponsiveContainer, XAxis, YAxis, } from "recharts"; import { Dialog, DialogContent, DialogHeader } from "~/components/ui/dialog"; import { Skeleton } from "~/components/ui/skeleton"; import apiService from "~/lib/api"; import { formatNumber } from "~/lib/utils"; import { ChartContainer } from "../ui/chart"; import { DropdownMenu, DropdownMenuButton, DropdownMenuContent, DropdownMenuItem, } from "../ui/dropdown-menu"; import { TruncatedText } from "../ui/truncatedText"; interface StrategicAlignmentData { strategic_theme: string; operational_fee_sum: number; percentage?: number; } interface DropDownConfig { isOpen: boolean; selectedValue: string; dropDownItems: Array; } type Action = | { type: "OPEN" } | { type: "CLOSE" } | { type: "SETVALUE"; value: Array } | { type: "SELECT"; value: string }; // const DropDownItems = [ // { // id: 0, // key: "همه مضامین", // Value: "همه مضامین", // }, // { // id: 1, // key: "ارزش های هم افزایی نوآورانه", // Value: "همه مضامین", // }, // { // id: 2, // key: "ارزش های خودکفایی نوآوورانه", // Value: "همه مضامین", // }, // { // id: 3, // key: "ارزش های فناوری های نوین", // Value: "همه مضامین", // }, // { // id: 4, // key: "ارزش های توسعه منابع انسانی", // Value: "همه مضامین", // }, // { // id: 5, // key: "ارزش های نوآوری سبز", // Value: "همه مضامین", // }, // ]; interface StrategicAlignmentPopupProps { open: boolean; onOpenChange: (open: boolean) => void; } // ✅ Chart config for shadcn/ui const chartConfig = { percentage: { label: "", color: "#3AEA83", }, }; const maxHeight = 150; const barHeights = () => Math.floor(Math.random() * maxHeight); const ChartSkeleton = () => (
{/* Chart bars */}
{[...Array(9)].map((_, i) => (
))}
{/* Left space for Y-axis label */}
); export function StrategicAlignmentPopup({ open, onOpenChange, }: StrategicAlignmentPopupProps) { const [data, setData] = useState([]); const [loading, setLoading] = useState(false); const [state, dispatch] = useReducer(reducer, { isOpen: false, selectedValue: "همه مضامین", dropDownItems: [], }); useEffect(() => { if (open) { fetchData(); } }, [open]); const fetchData = async () => { setLoading(true); try { const response = await apiService.select({ ProcessName: "project", OutputFields: [ "strategic_theme", "sum(operational_fee) as operational_fee_sum", ], GroupBy: ["strategic_theme"], }); const responseData = typeof response.data === "string" ? JSON.parse(response.data) : response.data; setBarItems(responseData); const dropDownItems = responseData.map( (item: any) => item.strategic_theme ); setDropDownValues(["همه مضامین", ...dropDownItems]); } catch (error) { console.error("Error fetching strategic alignment data:", error); } finally { setLoading(false); } }; const fetchDropDownItems = async (item: string) => { try { if (item !== "همه مضامین") { const response = await apiService.select({ ProcessName: "project", OutputFields: [ "value_technology_and_innovation", "sum(operational_fee)", ], Conditions: [["strategic_theme", "=", item]], GroupBy: ["value_technology_and_innovation"], }); const responseData = typeof response.data === "string" ? JSON.parse(response.data) : response.data; setBarItems(responseData); } else fetchData(); } catch (error) { console.error("Error fetching strategic alignment data:", error); } finally { setLoading(false); } }; function reducer(state: DropDownConfig, action: Action): DropDownConfig { switch (action.type) { case "OPEN": return { ...state, isOpen: true }; case "CLOSE": return { ...state, isOpen: false }; case "SETVALUE": return { ...state, dropDownItems: action.value }; case "SELECT": return { ...state, selectedValue: action.value }; default: return state; } } const toggleMenuHandler = () => { dispatch({ type: "OPEN", }); }; const selectItem = (item: string) => { dispatch({ type: "SELECT", value: item, }); dispatch({ type: "CLOSE", }); fetchDropDownItems(item); }; const setDropDownValues = (items: Array) => { dispatch({ type: "SETVALUE", value: items, }); }; const setBarItems = (responseData: any) => { const processedData = responseData .map((item: any) => ({ strategic_theme: item.strategic_theme || item.value_technology_and_innovation || "N/A", operational_fee_sum: Math.max(0, Number(item.operational_fee_sum)), })) .filter((item: StrategicAlignmentData) => item.strategic_theme !== ""); const total = processedData.reduce( (acc: number, item: StrategicAlignmentData) => acc + item.operational_fee_sum, 0 ); const dataWithPercentage = processedData.map( (item: StrategicAlignmentData) => ({ ...item, percentage: total > 0 ? Math.round((item.operational_fee_sum / total) * 100) : 0, }) ); setData(dataWithPercentage || []); }; return (
{state.selectedValue} {state.dropDownItems.map((item: string, key: number) => (
selectItem(item)} key={`${key}-${item}`} > {item}
))}
{loading ? ( ) : ( <> { const { x, y, payload } = props; return ( ); }} /> `${formatNumber(Math.round(value))}` } label={{ value: "تعداد برنامه ها", angle: -90, position: "insideLeft", fill: "#94a3b8", fontSize: 11, offset: 0, dy: 0, style: { textAnchor: "middle" }, }} /> {data.map((entry, index) => ( ))} `${formatNumber(Math.round(v))}` } /> )}
); }