diff --git a/app/components/dashboard/project-management/green-innovation-page.tsx b/app/components/dashboard/project-management/green-innovation-page.tsx index fc9c47a..27b90f9 100644 --- a/app/components/dashboard/project-management/green-innovation-page.tsx +++ b/app/components/dashboard/project-management/green-innovation-page.tsx @@ -1168,26 +1168,6 @@ export function GreenInnovationPage() { {selectedProjectDetails?.observer || "-"} - - {/*
-

- - حوزه کاری : -

- - {selectedProjectDetails?.observer || "-"} - -
*/} - - {/*
-

- - صنعت : -

- - {selectedProjectDetails?.observer || "-"} - -
*/} diff --git a/app/components/dashboard/project-management/innovation-built-inside-page.tsx b/app/components/dashboard/project-management/innovation-built-inside-page.tsx index b8a3bbf..5e963bb 100644 --- a/app/components/dashboard/project-management/innovation-built-inside-page.tsx +++ b/app/components/dashboard/project-management/innovation-built-inside-page.tsx @@ -23,28 +23,27 @@ import apiService from "~/lib/api"; import toast from "react-hot-toast"; import { FilterIcon, - Key, - Sparkle, - Zap, - Flame, - Building2, - PickaxeIcon, - UsersIcon, - UserIcon, RefreshCw, ChevronUp, ChevronDown, + Handshake, + CodeXml, + SquareUser, + Users, + User, } from "lucide-react"; import DashboardLayout from "../layout"; +import { LineChart, CartesianGrid, Legend, Line, ReferenceLine, ResponsiveContainer, Tooltip, XAxis, YAxis, Customized } from "recharts"; moment.loadPersian({ usePersianDigits: true }); -interface GreenInnovationData { - WorkflowID: string; + +interface innovationBuiltInDate { + WorkflowID: number; approved_budget: string; done_date: string | null; observer: string; project_description: string; - project_id: string; + project_id: number | null; project_no: string; project_rating: string; project_status: string; @@ -52,6 +51,25 @@ interface GreenInnovationData { title: string; } +interface DialogInfo { + WorkflowID: number + collaboration_model: string; // مشارکت استراتژیک + complexity_level: string; // فناوری سطح متوسط + developer_team_role: string; // نظارت + number_employees_involved: number | null; // ممکن است null باشد + participants_full_name: string; // مریم احمدی + project_description: string; // توضیحات پروژه + project_id: string; // "20922" + project_no: string; // "13" + project_rating: string; // "68" (اگر میخوای عدد باشد: number) + project_status: string; // پروپوزال + role_company_staff: string | null; // ممکن است null باشد + technology_maturity_level: string; // مرحله بلوغ + title: string; // عنوان پروژه + technology_params?: Array +} + + interface SortConfig { field: string; direction: "asc" | "desc"; @@ -112,28 +130,11 @@ interface InnovationStats { resolved_bottleneck_count: number; } -interface Params { - icon: any; - label: string; - value: number; - suffix: string; - percent: number; -} -interface RecycleParams { - water: Params; - food: Params; - power: Params; - oil: Params; -} - -interface stateCounter { - totalProjects: number; -} - -interface ChartDataItem { - name: string; - pv: any; // actual value - amt: number; // max value or target +interface TechnologyParameter { + WorkflowID: number; + domestic_technology_parameter_value: string; + foreign_technology_parameter_value: string; + technology_parameter_title: string; } enum projectStatus { @@ -164,8 +165,16 @@ const columns = [ { key: "details", label: "جزئیات پروژه", sortable: false, width: "140px" }, ]; +const data = [ + { name: 'افول', value: 10 }, + { name: 'رشد', value: 20 }, + { name: 'بلوغ', value: 15 }, + { name: 'معرفی', value: 25 }, + +]; + export function InnovationBuiltInsidePage() { - const [projects, setProjects] = useState([]); + const [projects, setProjects] = useState([]); const [loading, setLoading] = useState(false); const [loadingMore, setLoadingMore] = useState(false); const [currentPage, setCurrentPage] = useState(1); @@ -174,7 +183,7 @@ export function InnovationBuiltInsidePage() { const [totalCount, setTotalCount] = useState(0); const [actualTotalCount, setActualTotalCount] = useState(0); const [statsLoading, setStatsLoading] = useState(false); - const [stats, setStats] = useState(); + // const [stats, setStats] = useState(); const [sortConfig, setSortConfig] = useState({ field: "start_date", direction: "asc", @@ -185,11 +194,9 @@ export function InnovationBuiltInsidePage() { ); const [detailsDialogOpen, setDetailsDialogOpen] = useState(false); const [selectedProjectDetails, setSelectedProjectDetails] = - useState(null); + useState(); - const [innovationMetric, setInnovationMetric] = useState({ - }) const [sustainabilityStats, setSustainabilityStats] = useState({ currencySaving: { @@ -242,6 +249,8 @@ export function InnovationBuiltInsidePage() { }) + const [showDialogItems, setShowDialogItems] = useState(false) + const [countOfHighTech, setCountOfHighTech] = useState(0) const observerRef = useRef(null); @@ -257,11 +266,20 @@ export function InnovationBuiltInsidePage() { setSelectedProjects(newSelected); }; - const handleProjectDetails = (project: GreenInnovationData) => { - setSelectedProjectDetails(project); + const handleProjectDetails = async (project: DialogInfo) => { + setShowDialogItems(true) setDetailsDialogOpen(true); + + setSelectedProjectDetails(project); + await fetchDialogTbl(project.WorkflowID) + setTimeout(() => { + setShowDialogItems(false) + calculateProgressBar(+project.project_rating) + }, 500); }; + + const formatNumber = (value: string | number) => { if (!value) return "0"; const numericValue = typeof value === "string" ? parseFloat(value) : value; @@ -292,10 +310,13 @@ export function InnovationBuiltInsidePage() { "project_status", "project_rating", "project_description", - "start_date", - "done_date", - "approved_budget", - "observer" + "complexity_level", + "collaboration_model", + "developer_team_role", + "role_company_staff", + "number_employees_involved", + "participants_full_name", + "technology_maturity_level" ], Sorts: [[sortConfig.field, sortConfig.direction]], Conditions: [["type_of_innovation", "=", "نوآوری ساخت داخل"]], @@ -360,6 +381,43 @@ export function InnovationBuiltInsidePage() { } }; + + const fetchDialogTbl = async (tblId: number) => { + try { + const response = await apiService.select({ + ProcessName: "technology_parameter", + OutputFields: [ + "technology_parameter_title", + "domestic_technology_parameter_value", + "foreign_technology_parameter_value" + ], + Conditions: [["project_id", "=", tblId]], + }); + if (response.state === 0) { + const dataString = response.data; + if (dataString && typeof dataString === "string") { + const parsedData = JSON.parse(dataString); + setSelectedProjectDetails((prev: any) => ({ + ...prev, + technology_params: parsedData + })); + } + } + } catch (error) { + console.error("Error fetching projects:", error); + toast.error("خطا در دریافت اطلاعات پروژه‌ها"); + } + }; + + const calculateProgressBar = (val: number) => { + const pointer = document.getElementsByClassName('progressBarPointer')[0] as HTMLElement; + if (!pointer) return; + + const leftValue = val !== 0 ? `calc(${val}% - 100px)` : `calc(0% - 40px)`; + + pointer.style.left = leftValue; + }; + const loadMore = useCallback(() => { if (!loadingMore && hasMore && !loading) { setCurrentPage((prev) => prev + 1); @@ -368,7 +426,6 @@ export function InnovationBuiltInsidePage() { useEffect(() => { fetchProjects(true); - fetchTotalCount(); fetchStats(); }, [sortConfig, selectedProjects]); @@ -418,34 +475,7 @@ export function InnovationBuiltInsidePage() { setHasMore(true); }; - const fetchTotalCount = async () => { - try { - const response = await apiService.select({ - ProcessName: "project", - OutputFields: ["count(project_no)"], - Conditions: [["type_of_innovation", "=", "نوآوری سبز"]], - }); - if (response.state === 0) { - const dataString = response.data; - if (dataString && typeof dataString === "string") { - try { - const parsedData = JSON.parse(dataString); - if (Array.isArray(parsedData) && parsedData[0]) { - const count = parsedData[0].project_no_count || 0; - // Keep stats in sync if backend stats not yet loaded - setStats((prev) => ({ ...prev, totalProjects: count })); - } - } catch (parseError) { - console.error("Error parsing count data:", parseError); - } - } - } - } catch (error) { - console.error("Error fetching total count:", error); - } - }; - // Fetch aggregated stats from backend call API (innovation_process_function) const fetchStats = async () => { try { setStatsLoading(true); @@ -561,8 +591,8 @@ export function InnovationBuiltInsidePage() { setCountOfHighTech(normalized.countOfHighTech) }; - const renderCellContent = (item: GreenInnovationData, column: any) => { - const value = item[column.key as keyof GreenInnovationData]; + const renderCellContent = (item: innovationBuiltInDate, column: any) => { + const value = item[column.key as keyof innovationBuiltInDate]; switch (column.key) { case "select": @@ -654,12 +684,6 @@ export function InnovationBuiltInsidePage() { return el; }; - // const [chartData, setChartData] = useState>([ - // { name: recycleParams.water.label, pv: 70, amt: 80 }, - // { name: recycleParams.power.label, pv: 45, amt: 60 }, - // { name: recycleParams.oil.label, pv: 90, amt: 75 }, - // { name: recycleParams.food.label, pv: 30, amt: 50 }, - // ]); return ( @@ -807,8 +831,6 @@ export function InnovationBuiltInsidePage() { } - - { loading ?
@@ -959,110 +981,283 @@ export function InnovationBuiltInsidePage() {
+ {/* Project Details Dialog */} - + شرح پروژه -
- {/* Project Description */} -
-

{selectedProjectDetails?.title}

-

- {selectedProjectDetails?.project_description || "-"} -

+
+
+ + { + showDialogItems ?
+
+
+
+
+
+
:
+

{selectedProjectDetails?.title}

+

+ {selectedProjectDetails?.project_description || "-"} +

+
+ } +

دانش فنی محصول جدید

+ { + showDialogItems ?
+
+
+
+
+
+
+
+
+
+ +
+
+ + + سطح تکنولوژی + +
+
+
+
:
+
+
+
+ سطح پایین +
+
+ سطح متوسط +
+
+ سطح بالا +
+
+
+
+ + سطح تکنولوژی +
+
+
+
+ } + +
+

مشارکت در پروژه

+ { + showDialogItems ?
+ {[...Array(4)].map((_, i) => ( +
+
+
+
+
+
+
+ ))} +
:
+
+
+ +
+ مدل همکاری: + {selectedProjectDetails?.collaboration_model} +
+
+
+ +
+ نقش تیم توسعه دهنده: + {selectedProjectDetails?.developer_team_role} +
+
+
+ +
+ نقش کارکنان شرکت: + نظارت کننده +
+
+
+ +
+ تعداد کارکنان درگیر: + {selectedProjectDetails?.number_employees_involved ?? 0} +
+
+
+ +
+ +
+ لیست کارکنان : + {selectedProjectDetails?.participants_full_name} +
+
+ +
+ } + + + + + +
{/* Project Details */} -
-
جزئیات پروژه
+
+ { + showDialogItems ?
+ {[...Array(5)].map((_, rowIndex) => ( +
+
+
+ ))} +
:
+
+ شاخص مقایسه با نمونه خارجی + نمونه داخلی + نمونه خارجی +
+
+ { + selectedProjectDetails?.technology_params?.map((el, index) => { + return
+ {el.technology_parameter_title} +
+ {el.domestic_technology_parameter_value} + میلیون لیتر +
+
+ {el.foreign_technology_parameter_value} + میلیون لیتر +
+
+ + }) + + } +
+
+ } +
+ { + showDialogItems ?
+ {[...Array(4)].map((_, i) => ( +
+ ))} + + {[...Array(5)].map((_, i) => ( +
+ ))} +
: + + + + + + + + { + const { xAxisMap, width, height } = props; + const xAxes = Object.values(xAxisMap || {}); + if (!xAxes.length) return null; + + const xAxis: any = xAxes[0]; + const ticks = xAxis?.ticks || []; + const tick = ticks.find((t: any) => { + return t && (t.value === "بلوغ" || (t.payload && t.payload.value === "بلوغ")); + }); + + const x = (tick && tick.coordinate) ?? width / 2 + 80 + + const rectWidth = 140; + const rectHeight = 28; + const rectX = x - rectWidth / 2; + + const axisHeight = xAxis?.height ?? 40; + const rectY = (height - axisHeight) - 30; + + return ( + + + + سطح بلوغ تکنولوژی + + + ); + }} + /> + + + } + + + -
-

- - زمان شروع: -

- - {selectedProjectDetails?.start_date - ? moment( - selectedProjectDetails?.start_date, - "YYYY-MM-DD" - ).format("YYYY/MM/DD") - : "-"} -
- -
-

- - زمان پایان: -

- - {selectedProjectDetails?.done_date - ? moment( - selectedProjectDetails?.done_date, - "YYYY-MM-DD" - ).format("YYYY/MM/DD") - : "-"} - -
- -
-

- - هزینه برآورد شده: -

- - {formatNumber( - Number( - selectedProjectDetails?.approved_budget.replaceAll( - ",", - "" - ) - ) - ) || "-"} - -
-
-

- - نفر مرتبط: -

- - {selectedProjectDetails?.observer || "-"} - -
- - {/*
-

- - حوزه کاری : -

- - {selectedProjectDetails?.observer || "-"} - -
*/} - - {/*
-

- - صنعت : -

- - {selectedProjectDetails?.observer || "-"} - -
*/}
+
-
+ ); }