diff --git a/app/components/dashboard/project-management/digital-innovation-page.tsx b/app/components/dashboard/project-management/digital-innovation-page.tsx index 080e16a..c55a190 100644 --- a/app/components/dashboard/project-management/digital-innovation-page.tsx +++ b/app/components/dashboard/project-management/digital-innovation-page.tsx @@ -1,10 +1,30 @@ -import { useState, useEffect, useCallback, useRef, useMemo } from "react"; -import { DashboardLayout } from "../layout"; -import { Card, CardContent } from "~/components/ui/card"; -import { Button } from "~/components/ui/button"; -import { Badge } from "~/components/ui/badge"; -import { Checkbox } from "~/components/ui/checkbox"; +import { + BrainCircuit, + ChevronDown, + ChevronUp, + Database, + Key, + LoaderCircle, + RefreshCw, + Sprout, + TrendingDown, + TrendingUp, + Zap, +} from "lucide-react"; import moment from "moment-jalaali"; +import { useCallback, useEffect, useMemo, useRef, useState } from "react"; +import toast from "react-hot-toast"; +import { Badge } from "~/components/ui/badge"; +import { Button } from "~/components/ui/button"; +import { Card, CardContent } from "~/components/ui/card"; +import { Checkbox } from "~/components/ui/checkbox"; +import { CustomBarChart } from "~/components/ui/custom-bar-chart"; +import { + Dialog, + DialogContent, + DialogHeader, + DialogTitle, +} from "~/components/ui/dialog"; import { Table, TableBody, @@ -13,26 +33,9 @@ import { TableHeader, TableRow, } from "~/components/ui/table"; -import { - Dialog, - DialogContent, - DialogHeader, - DialogTitle, -} from "~/components/ui/dialog"; -import { ChevronUp, ChevronDown, RefreshCw } from "lucide-react"; import apiService from "~/lib/api"; -import toast from "react-hot-toast"; -import { - Database, - Zap, - TrendingDown, - TrendingUp, - Key, - Sprout, - BrainCircuit, - LoaderCircle, -} from "lucide-react"; -import { CustomBarChart } from "~/components/ui/custom-bar-chart"; +import { formatCurrency } from "~/lib/utils"; +import { DashboardLayout } from "../layout"; moment.loadPersian({ usePersianDigits: true }); @@ -492,16 +495,6 @@ export function DigitalInnovationPage() { // fetchStats(); // }; - const formatCurrency = (amount: string | number) => { - if (!amount) return "0 ریال"; - const numericAmount = - typeof amount === "string" - ? parseFloat(amount.replace(/,/g, "")) - : amount; - if (isNaN(numericAmount)) return "0 ریال"; - return new Intl.NumberFormat("fa-IR").format(numericAmount) + " ریال"; - }; - const renderProgress = useMemo(() => { const total = 10; for (let i = 0; i < rating.length; i++) { @@ -625,18 +618,18 @@ export function DigitalInnovationPage() { return ( -
+
{/* Stats Cards */}
{/* Stats Grid */}
- {loading || statsLoading + {loading ? // Loading skeleton for stats cards - matching new design Array.from({ length: 4 }).map((_, index) => (
@@ -698,7 +691,7 @@ export function DigitalInnovationPage() {
{/* Process Impacts Chart */} - + {/* */} {/* Footer */} +
+
+
+ +
+ کل پروژه‌ها:{" "} + + {formatNumber(actualTotalCount)} + +
+ +
+ + + + +
+ +
+ میانگین:{" "} + + {formatNumber( + ((stats.avarageProjectScore ?? 0) as number).toFixed?.(1) ?? + 0 + )} + +
+ +
+
+
+ + {/*
@@ -881,7 +907,7 @@ export function DigitalInnovationPage() {
-
+
*/}
diff --git a/app/components/dashboard/project-management/green-innovation-page.tsx b/app/components/dashboard/project-management/green-innovation-page.tsx index cfc9d05..116a4bb 100644 --- a/app/components/dashboard/project-management/green-innovation-page.tsx +++ b/app/components/dashboard/project-management/green-innovation-page.tsx @@ -1,4 +1,4 @@ -import moment from "moment-jalaali"; +// import moment from "moment-jalaali"; import { useCallback, useEffect, useRef, useState } from "react"; import { Bar, @@ -44,9 +44,10 @@ import { } from "lucide-react"; import toast from "react-hot-toast"; import apiService from "~/lib/api"; +import { formatCurrency } from "~/lib/utils"; import DashboardLayout from "../layout"; -moment.loadPersian({ usePersianDigits: true }); +// moment.loadPersian({ usePersianDigits: true }); interface GreenInnovationData { WorkflowID: string; approved_budget: string; @@ -690,8 +691,8 @@ export function GreenInnovationPage() {
{/* Stats Cards */} -
-
+
+
{loading || statsLoading ? // Loading skeleton for stats cards - matching new design Array.from({ length: 2 }).map((_, index) => ( @@ -948,7 +949,7 @@ export function GreenInnovationPage() {
- +
{columns.map((column) => ( @@ -1050,14 +1051,14 @@ export function GreenInnovationPage() {
-
-
-
+
+
+
کل پروژه ها :{formatNumber(actualTotalCount)}
-
+
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 6d7f46f..ddf6848 100644 --- a/app/components/dashboard/project-management/innovation-built-inside-page.tsx +++ b/app/components/dashboard/project-management/innovation-built-inside-page.tsx @@ -1,4 +1,3 @@ -import moment from "moment-jalaali"; import { useCallback, useEffect, useRef, useState } from "react"; import { Badge } from "~/components/ui/badge"; import { Button } from "~/components/ui/button"; @@ -40,10 +39,9 @@ import { XAxis, } from "recharts"; import apiService from "~/lib/api"; +import { formatCurrency } from "~/lib/utils"; import DashboardLayout from "../layout"; -moment.loadPersian({ usePersianDigits: true }); - interface innovationBuiltInDate { WorkflowID: number; approved_budget: string; @@ -193,9 +191,8 @@ export function InnovationBuiltInsidePage() { direction: "asc", }); const [tblAvarage, setTblAvarage] = useState(0); - const [selectedProjects, setSelectedProjects] = useState< - Set - >(new Set()); + const [selectedProjects, setSelectedProjects] = + useState>(); const [detailsDialogOpen, setDetailsDialogOpen] = useState(false); const [selectedProjectDetails, setSelectedProjectDetails] = useState(); @@ -425,7 +422,6 @@ export function InnovationBuiltInsidePage() { useEffect(() => { fetchProjects(true); - fetchStats(); }, [sortConfig]); useEffect(() => { @@ -485,7 +481,7 @@ export function InnovationBuiltInsidePage() { const raw = await apiService.call({ innovation_construction_inside_function: { project_ids: - selectedProjects.size > 0 + selectedProjects && selectedProjects?.size > 0 ? Array.from(selectedProjects).join(" , ") : "", }, @@ -621,7 +617,7 @@ export function InnovationBuiltInsidePage() { case "select": return ( handleSelectProject(item?.project_id)} className="data-[state=checked]:bg-emerald-600 data-[state=checked]:border-emerald-600 cursor-pointer" /> @@ -709,9 +705,9 @@ export function InnovationBuiltInsidePage() { return ( -
+
{/* Stats Cards */} -
+
{statsLoading ? // Loading skeleton for stats cards - matching new design @@ -977,6 +973,37 @@ export function InnovationBuiltInsidePage() {
+
+
+ +
+ کل پروژه‌ها:{" "} + + {formatNumber(actualTotalCount)} + +
+ +
+ + + + +
+ +
+ میانگین:{" "} + + {formatNumber( + ((tblAvarage ?? 0) as number).toFixed?.(1) ?? 0 + )} + +
+ +
+
+
+ + {/*
@@ -1001,13 +1028,13 @@ export function InnovationBuiltInsidePage() {
-
+
*/}
{/* Project Details Dialog */} - + شرح پروژه @@ -1160,12 +1187,12 @@ export function InnovationBuiltInsidePage() {
) : (
-
- +
+ شاخص مقایسه با نمونه خارجی - نمونه داخلی - نمونه خارجی + نمونه داخلی + نمونه خارجی
{selectedProjectDetails?.technology_params?.map( @@ -1236,7 +1263,7 @@ export function InnovationBuiltInsidePage() { ([]); const [loading, setLoading] = useState(false); @@ -402,7 +400,7 @@ export function ManageIdeasTechPage() { try { const response = await apiService.select({ ProcessName: "idea", - OutputFields: ["count(idea_no)"], + OutputFields: ["count(idea_title)"], Conditions: [], }); @@ -412,7 +410,7 @@ export function ManageIdeasTechPage() { try { const parsedData = JSON.parse(dataString); if (Array.isArray(parsedData) && parsedData[0]) { - setActualTotalCount(parsedData[0].project_no_count || 0); + setActualTotalCount(parsedData[0].idea_title_count || 0); } } catch (parseError) { console.error("Error parsing count data:", parseError); @@ -424,24 +422,6 @@ export function ManageIdeasTechPage() { } }; - const formatCurrency = (amount: string | number) => { - if (!amount) return "0 ریال"; - // Remove commas and convert to number - const numericAmount = - typeof amount === "string" - ? parseFloat(amount.replace(/,/g, "")) - : amount; - if (isNaN(numericAmount)) return "0 ریال"; - return new Intl.NumberFormat("fa-IR").format(numericAmount) + " ریال"; - }; - - // const formatNumber = (value: string | number) => { - // if (value === undefined || value === null || value === "") return "0"; - // const numericValue = typeof value === "string" ? Number(value) : value; - // if (Number.isNaN(numericValue)) return "0"; - // return new Intl.NumberFormat("fa-IR").format(numericValue as number); - // }; - const toPersianDigits = (input: string | number): string => { const str = String(input); const map: Record = { @@ -607,21 +587,6 @@ export function ManageIdeasTechPage() { ); } - // case "strategic_theme": - // case "value_technology_and_innovation": - // case "type_of_innovation": - // case "innovation": - // return ( - // - // {String(value) || "-"} - // - // - // ); case "idea_income": return ( @@ -631,7 +596,9 @@ export function ManageIdeasTechPage() { case "personnel_number": // case "idea_originality": return ( - {formatNumber(value as any)} + + {toPersianDigits(value as any)}{" "} + ); case "idea_registration_date": return ( diff --git a/app/components/dashboard/project-management/process-innovation-page.tsx b/app/components/dashboard/project-management/process-innovation-page.tsx index 1512902..83d5ca3 100644 --- a/app/components/dashboard/project-management/process-innovation-page.tsx +++ b/app/components/dashboard/project-management/process-innovation-page.tsx @@ -439,7 +439,7 @@ export function ProcessInnovationPage() { const stats = data[0]; const normalized: InnovationStats = { totalProjects: parseNum(stats?.count_innovation_process_projects), - averageScore: parseNum(stats?.average_project_score), + averageScore: parseFloat(data[0].average_project_score), productionStopsPreventionSum: parseNum(stats?.sum_stopping_production), bottleneckRemovalCount: parseNum(stats?.count_throat_removal), currencyReductionSum: parseNum(stats?.sum_reduction_value_currency), @@ -828,9 +828,7 @@ export function ProcessInnovationPage() {
میانگین :‌
- {formatNumber( - ((stats.averageScore ?? 0) as number).toFixed?.(1) ?? 0 - )} + {formatNumber(((stats.averageScore ?? 0) as number) ?? 0)}
diff --git a/app/components/dashboard/project-management/project-management-page.tsx b/app/components/dashboard/project-management/project-management-page.tsx index 44401bd..032277e 100644 --- a/app/components/dashboard/project-management/project-management-page.tsx +++ b/app/components/dashboard/project-management/project-management-page.tsx @@ -1,7 +1,8 @@ -import { useState, useEffect, useCallback, useRef } from "react"; -import { DashboardLayout } from "../layout"; -import { Card, CardContent } from "~/components/ui/card"; +import { ChevronDown, ChevronUp, RefreshCw } from "lucide-react"; +import { useCallback, useEffect, useRef, useState } from "react"; +import toast from "react-hot-toast"; import { Badge } from "~/components/ui/badge"; +import { Card, CardContent } from "~/components/ui/card"; import { Table, TableBody, @@ -10,9 +11,9 @@ import { TableHeader, TableRow, } from "~/components/ui/table"; -import { ChevronUp, ChevronDown, RefreshCw } from "lucide-react"; import apiService from "~/lib/api"; -import toast from "react-hot-toast"; +import { formatCurrency } from "~/lib/utils"; +import { DashboardLayout } from "../layout"; interface ProjectData { WorkflowID: number; @@ -351,17 +352,6 @@ export function ProjectManagementPage() { fetchTotalCount(); }; - const formatCurrency = (amount: string | number) => { - if (!amount) return "0 ریال"; - // Remove commas and convert to number - const numericAmount = - typeof amount === "string" - ? parseFloat(amount.replace(/,/g, "")) - : amount; - if (isNaN(numericAmount)) return "0 ریال"; - return new Intl.NumberFormat("fa-IR").format(numericAmount) + " ریال"; - }; - const formatNumber = (value: string | number) => { if (value === undefined || value === null || value === "") return "0"; const numericValue = typeof value === "string" ? Number(value) : value; diff --git a/app/components/ui/card.tsx b/app/components/ui/card.tsx index 901efad..bacd208 100644 --- a/app/components/ui/card.tsx +++ b/app/components/ui/card.tsx @@ -1,6 +1,6 @@ -import * as React from "react" +import * as React from "react"; -import { cn } from "~/lib/utils" +import { cn } from "~/lib/utils"; const Card = React.forwardRef< HTMLDivElement, @@ -9,13 +9,13 @@ const Card = React.forwardRef<
-)) -Card.displayName = "Card" +)); +Card.displayName = "Card"; const CardHeader = React.forwardRef< HTMLDivElement, @@ -26,8 +26,8 @@ const CardHeader = React.forwardRef< className={cn("flex flex-col space-y-1.5 p-6", className)} {...props} /> -)) -CardHeader.displayName = "CardHeader" +)); +CardHeader.displayName = "CardHeader"; const CardTitle = React.forwardRef< HTMLParagraphElement, @@ -41,8 +41,8 @@ const CardTitle = React.forwardRef< )} {...props} /> -)) -CardTitle.displayName = "CardTitle" +)); +CardTitle.displayName = "CardTitle"; const CardDescription = React.forwardRef< HTMLParagraphElement, @@ -53,16 +53,16 @@ const CardDescription = React.forwardRef< className={cn("text-sm text-muted-foreground", className)} {...props} /> -)) -CardDescription.displayName = "CardDescription" +)); +CardDescription.displayName = "CardDescription"; const CardContent = React.forwardRef< HTMLDivElement, React.HTMLAttributes >(({ className, ...props }, ref) => (
-)) -CardContent.displayName = "CardContent" +)); +CardContent.displayName = "CardContent"; const CardFooter = React.forwardRef< HTMLDivElement, @@ -73,7 +73,14 @@ const CardFooter = React.forwardRef< className={cn("flex items-center p-6 pt-0", className)} {...props} /> -)) -CardFooter.displayName = "CardFooter" +)); +CardFooter.displayName = "CardFooter"; -export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent } +export { + Card, + CardContent, + CardDescription, + CardFooter, + CardHeader, + CardTitle, +}; diff --git a/app/lib/utils.ts b/app/lib/utils.ts index 2cee588..dc79b88 100644 --- a/app/lib/utils.ts +++ b/app/lib/utils.ts @@ -11,3 +11,12 @@ export const formatNumber = (value: string | number) => { if (isNaN(numericValue)) return "0"; return new Intl.NumberFormat("fa-IR").format(numericValue); }; + +export const formatCurrency = (amount: string | number) => { + if (!amount) return "0 ریال"; + // Remove commas and convert to number + const numericAmount = + typeof amount === "string" ? parseFloat(amount.replace(/,/g, "")) : amount; + if (isNaN(numericAmount)) return "0 ریال"; + return new Intl.NumberFormat("fa-IR").format(numericAmount) + " ریال"; +};