feat/digital-innovation #1

Merged
Saeed0920 merged 6 commits from feat/digital-innovation into main 2025-08-27 13:36:39 +03:30
2 changed files with 52 additions and 122 deletions
Showing only changes of commit b06e569e39 - Show all commits

View File

@ -1,4 +1,4 @@
import { useState, useEffect, useCallback, useRef } from "react";
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";
@ -41,7 +41,6 @@ import {
LoaderCircle,
} from "lucide-react";
import { CustomBarChart } from "~/components/ui/custom-bar-chart";
import { color } from "d3";
moment.loadPersian({ usePersianDigits: true });
@ -74,7 +73,7 @@ interface DigitalInnovationMetrics {
// Normalized interface for digital innovation stats
interface DigitalInnovationStats {
totalDigitalProjects: number;
// totalDigitalProjects: number;
increasedRevenue: number;
increasedRevenuePercent: number;
reduceCosts: number;
@ -98,6 +97,8 @@ interface ProcessInnovationData {
project_status: string;
project_rating: string;
project_description: string;
total_project: number;
WorkflowID: number;
}
interface HouseItem {
@ -128,6 +129,7 @@ const columns = [
sortable: true,
width: "140px",
},
{ key: "details", label: "جزئیات پروژه", sortable: false, width: "140px" },
];
export function DigitalInnovationPage() {
@ -140,8 +142,9 @@ export function DigitalInnovationPage() {
const [totalCount, setTotalCount] = useState(0);
const [actualTotalCount, setActualTotalCount] = useState(0);
const [statsLoading, setStatsLoading] = useState(false);
const [rating, setRating] = useState<ListItem[]>([]);
const [dialogInfo, setDialogInfo] = useState<ProcessInnovationData>();
const [stats, setStats] = useState<DigitalInnovationStats>({
totalDigitalProjects: 0,
increasedRevenue: 0,
increasedRevenuePercent: 0,
reduceCosts: 0,
@ -173,21 +176,16 @@ export function DigitalInnovationPage() {
}
};
// const handleSelectProject = (projectNo: string) => {
// const newSelected = new Set(selectedProjects);
// if (newSelected.has(projectNo)) {
// newSelected.delete(projectNo);
// } else {
// newSelected.add(projectNo);
// }
// setSelectedProjects(newSelected);
// };
// const handleProjectDetails = (project: ProcessInnovationData) => {
// console.log(project);
// // setSelectedProjectDetails(project);
// setDetailsDialogOpen(true);
// };
const handleProjectDetails = (project: ProcessInnovationData) => {
const model: ListItem = {
label: `فرآیند-${project.WorkflowID}`,
development: +project.project_rating,
house: [],
};
setRating([model]);
setDialogInfo(project);
setDetailsDialogOpen(true);
};
const formatNumber = (value: string | number) => {
if (!value) return "0";
@ -260,9 +258,17 @@ export function DigitalInnovationPage() {
OutputFields: [
"project_no",
"title",
"project_description",
"project_status",
"project_rating",
"project_description",
"digital_competence",
"originality_digital_solution",
"digital_puberty_elements",
"digital_capability",
"operational_plan",
"desired_strategy",
"innovation_cost_reduction",
"reduce_costs_percent"
],
Sorts: [["start_date", "asc"]],
Conditions: [["type_of_innovation", "=", "نوآوری دیجیتال"]],
@ -389,7 +395,7 @@ export function DigitalInnovationPage() {
const response = await apiService.select({
ProcessName: "project",
OutputFields: ["count(project_no)"],
Conditions: [["type_of_innovation", "=", "نوآوری در فرآیند"]],
Conditions: [["type_of_innovation", "=", "نوآوری دیجیتال"]],
});
if (response.state === 0) {
@ -438,11 +444,7 @@ export function DigitalInnovationPage() {
}
return 0;
};
const normalized: DigitalInnovationStats = {
totalDigitalProjects: parseNum(
payload?.count_innovation_digital_projects
),
increasedRevenue: parseNum(payload?.increased_revenue),
increasedRevenuePercent: parseNum(payload?.increased_revenue_percent),
reduceCosts: parseNum(payload?.reduce_costs),
@ -465,15 +467,15 @@ export function DigitalInnovationPage() {
}
};
const handleRefresh = () => {
fetchingRef.current = false;
setCurrentPage(1);
setProjects([]);
setHasMore(true);
fetchTable(true);
fetchTotalCount();
fetchStats();
};
// const handleRefresh = () => {
// fetchingRef.current = false;
// setCurrentPage(1);
// setProjects([]);
// setHasMore(true);
// fetchTable(true);
// fetchTotalCount();
// fetchStats();
// };
const formatCurrency = (amount: string | number) => {
if (!amount) return "0 ریال";
@ -485,67 +487,10 @@ export function DigitalInnovationPage() {
return new Intl.NumberFormat("fa-IR").format(numericAmount) + " ریال";
};
// const formatPercentage = (value: string | number) => {
// if (!value) return "0%";
// const numericValue = typeof value === "string" ? parseFloat(value) : value;
// if (isNaN(numericValue)) return "0%";
// return `${numericValue.toFixed(1)}%`;
// };
// const getStatusColor = (status: string) => {
// switch (status?.toLowerCase()) {
// case "فعال":
// return "#3AEA83";
// case "متوقف":
// return "#F76276";
// case "تکمیل شده":
// return "#32CD32";
// default:
// return "#6B7280";
// }
// };
// const getRatingColor = (rating: string) => {
// const ratingNum = parseFloat(rating);
// if (isNaN(ratingNum)) return "#6B7280";
// if (ratingNum >= 8) return "#3AEA83";
// if (ratingNum >= 6) return "#69C8EA";
// if (ratingNum >= 4) return "#FFD700";
// return "#F76276";
// };
const [list, setList] = useState<ListItem[]>([
{
label: "فرآیند1",
development: 40,
house: [],
},
{
label: "فرآیند2",
development: 30,
house: [],
},
{
label: "فرآیند3",
development: 40,
house: [],
},
{
label: "فرآیند4",
development: 50,
house: [],
},
{
label: "فرآیند5",
development: 91.6,
house: [],
},
]);
const renderProgress = () => {
const renderProgress = useMemo(() => {
const total = 10;
for (let i = 0; i < list.length; i++) {
const currentElm = list[i];
for (let i = 0; i < rating.length; i++) {
const currentElm = rating[i];
currentElm.house = [];
const greenBoxes = Math.floor((total * currentElm.development) / 100);
const partialPercent =
@ -561,18 +506,14 @@ export function DigitalInnovationPage() {
index: greenBoxes + 1,
style: `linear-gradient(
to right,
lch(87 118.17 147.55) 0%,
lch(87 118.17 147.55) ${partialPercent * 100}%,
oklch(76.5% 0.177 163.223) 0%,
oklch(76.5% 0.177 163.223) ${partialPercent * 100}%,
oklch(55.1% 0.027 264.364) ${partialPercent * 100}%,
oklch(55.1% 0.027 264.364) 100%
)`,
});
}
};
useEffect(() => {
renderProgress();
}, []);
}, [rating]);
const renderCellContent = (item: any, column: any) => {
const value = item[column.key as keyof ProcessInnovationData];
@ -591,7 +532,7 @@ export function DigitalInnovationPage() {
<Button
variant="ghost"
size="sm"
// onClick={() => handleProjectDetails(item)}
onClick={() => handleProjectDetails(item)}
className="text-emerald-400 hover:text-emerald-300 hover:bg-emerald-500/20 p-2 h-auto"
>
جزئیات بیشتر
@ -684,7 +625,6 @@ export function DigitalInnovationPage() {
))
: statsCards.map((card) => (
<Card
onClick={() => setDetailsDialogOpen(true)}
key={card.id}
className="bg-[linear-gradient(to_bottom_left,#464861,50%,#111628)] backdrop-blur-sm border-gray-700/50"
>
@ -877,9 +817,7 @@ export function DigitalInnovationPage() {
<div className="grid grid-cols-6 gap-4 text-sm text-gray-300 font-persian">
<div className="text-center gap-2 items-center flex">
<div className="text-base text-gray-401 mb-1">
{" "}
کل پروژه ها :{" "}
{formatNumber(stats.totalDigitalProjects || actualTotalCount)}
کل پروژه ها :{formatNumber(actualTotalCount)}
</div>
</div>
{/* Project number column - empty */}
@ -922,20 +860,10 @@ export function DigitalInnovationPage() {
<div className="body grid grid-cols-[40%_20%_40%]">
<div className="border-l-2 border-l-gray-600 px-6">
<span className="title text-lg font-bold">
توسعه فناوری جدید در تولید پلیاتیلن
{dialogInfo?.title}
</span>
<p className="p-0 py-4 pb-8 text-justify text-base">
در این پروژه، هدف اصلی طراحی یک نقشه راه جامع برای تحول دیجیتال
در صنعت پتروشیمی بوده است. با توجه به روند سریع تغییرات
تکنولوژیکی و رقابت فزاینده در بازار، این پروژه به شناسایی و
پیادهسازی استراتژیهای دیجیتال برای بهینهسازی فرآیندهای تولید،
مدیریت منابع، و ارتقاء بهرهوری در واحدهای مختلف پتروشیمی
پرداخته است. در این پروژه، هدف اصلی طراحی یک نقشه راه جامع برای
تحول دیجیتال در صنعت پتروشیمی بوده است. با توجه به روند سریع
تغییرات تکنولوژیکی و رقابت فزاینده در بازار، این پروژه به
شناسایی و پیادهسازی استراتژیهای دیجیتال برای بهینهسازی
فرآیندهای تولید، مدیریت منابع، و ارتقاء بهرهوری در واحدهای
مختلف پتروشیمی پرداخته است.
{dialogInfo?.project_description}
</p>
<div className="details flex flex-col gap-3">
<span className="text-lg font-bold">ویژگی های اصلی پروژه:</span>
@ -1100,9 +1028,12 @@ export function DigitalInnovationPage() {
<span>درصد پیشرفت</span>
</div>
<div className="rows flex flex-col gap-2">
{list.map((el, index) => {
{rating.map((el, index) => {
return (
<div className="row border-b-1 border-b-[#3F415A] pb-2 px-2 flex justify-between items-center last:border-none">
<div
className="row border-b-1 border-b-[#3F415A] pb-2 px-2 flex justify-between items-center last:border-none"
key={`rating-${index}`}
>
<span className="pName">{el.label}</span>
<div
className="ProgressBar flex flex-row gap-1 rounded-md overflow-hidden"

View File

@ -149,7 +149,6 @@ export function ProcessInnovationPage() {
};
const handleProjectDetails = (project: ProcessInnovationData) => {
console.log(project);
setSelectedProjectDetails(project);
setDetailsDialogOpen(true);
};
@ -640,7 +639,7 @@ export function ProcessInnovationPage() {
{/* Process Impacts Chart */}
<Card className="bg-[linear-gradient(to_bottom_left,#464861,50%,#111628)] backdrop-blur-sm rounded-2xl w-full overflow-hidden">
<CardContent className="p-4">
<CardContent >
<CustomBarChart
title="تاثیرات فرآیندی به صورت درصد مقایسه ای"
loading={statsLoading}