finish:digital-inovation page
This commit is contained in:
parent
b06e569e39
commit
c23e82604e
|
|
@ -91,14 +91,29 @@ enum DigitalCardLabel {
|
||||||
decreaseEnergy = "کاهش مصرف انرژی",
|
decreaseEnergy = "کاهش مصرف انرژی",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum projectStatus {
|
||||||
|
propozal = "پروپوزال",
|
||||||
|
contract = "پیشنویس قرارداد",
|
||||||
|
inprogress = "در حال انجام",
|
||||||
|
stop = "متوقف شده",
|
||||||
|
mafasa = "مرحله مفاصا",
|
||||||
|
finish = "پایان یافته",
|
||||||
|
}
|
||||||
interface ProcessInnovationData {
|
interface ProcessInnovationData {
|
||||||
project_no: string;
|
|
||||||
title: string;
|
|
||||||
project_status: string;
|
|
||||||
project_rating: string;
|
|
||||||
project_description: string;
|
|
||||||
total_project: number;
|
|
||||||
WorkflowID: number;
|
WorkflowID: number;
|
||||||
|
desired_strategy: string;
|
||||||
|
digital_capability: string;
|
||||||
|
digital_competence: string;
|
||||||
|
digital_puberty_elements: string;
|
||||||
|
innovation_cost_reduction: number | string;
|
||||||
|
operational_plan: string;
|
||||||
|
originality_digital_solution: string;
|
||||||
|
project_description: string;
|
||||||
|
project_no: string;
|
||||||
|
project_rating: number | string;
|
||||||
|
project_status: string;
|
||||||
|
reduce_costs_percent: number;
|
||||||
|
title: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface HouseItem {
|
interface HouseItem {
|
||||||
|
|
@ -162,8 +177,7 @@ export function DigitalInnovationPage() {
|
||||||
new Set()
|
new Set()
|
||||||
);
|
);
|
||||||
const [detailsDialogOpen, setDetailsDialogOpen] = useState(false);
|
const [detailsDialogOpen, setDetailsDialogOpen] = useState(false);
|
||||||
// const [selectedProjectDetails, setSelectedProjectDetails] =
|
const [avarage, setAvarage] = useState<number>(0);
|
||||||
// useState<ProcessInnovationData | null>(null);
|
|
||||||
const observerRef = useRef<HTMLDivElement>(null);
|
const observerRef = useRef<HTMLDivElement>(null);
|
||||||
const fetchingRef = useRef(false);
|
const fetchingRef = useRef(false);
|
||||||
|
|
||||||
|
|
@ -194,7 +208,6 @@ export function DigitalInnovationPage() {
|
||||||
return new Intl.NumberFormat("fa-IR").format(numericValue);
|
return new Intl.NumberFormat("fa-IR").format(numericValue);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Stats cards data - computed from projects data
|
|
||||||
const statsCards: StatsCard[] = [
|
const statsCards: StatsCard[] = [
|
||||||
{
|
{
|
||||||
id: "production-stops-prevention",
|
id: "production-stops-prevention",
|
||||||
|
|
@ -268,9 +281,9 @@ export function DigitalInnovationPage() {
|
||||||
"operational_plan",
|
"operational_plan",
|
||||||
"desired_strategy",
|
"desired_strategy",
|
||||||
"innovation_cost_reduction",
|
"innovation_cost_reduction",
|
||||||
"reduce_costs_percent"
|
"reduce_costs_percent",
|
||||||
],
|
],
|
||||||
Sorts: [["start_date", "asc"]],
|
Sorts: [[sortConfig.field, sortConfig.direction]],
|
||||||
Conditions: [["type_of_innovation", "=", "نوآوری دیجیتال"]],
|
Conditions: [["type_of_innovation", "=", "نوآوری دیجیتال"]],
|
||||||
Pagination: { PageNumber: pageToFetch, PageSize: pageSize },
|
Pagination: { PageNumber: pageToFetch, PageSize: pageSize },
|
||||||
});
|
});
|
||||||
|
|
@ -280,10 +293,11 @@ export function DigitalInnovationPage() {
|
||||||
const dataString = response.data;
|
const dataString = response.data;
|
||||||
if (dataString && typeof dataString === "string") {
|
if (dataString && typeof dataString === "string") {
|
||||||
try {
|
try {
|
||||||
const parsedData = JSON.parse(dataString);
|
const parsedData: ProcessInnovationData = JSON.parse(dataString);
|
||||||
if (Array.isArray(parsedData)) {
|
if (Array.isArray(parsedData)) {
|
||||||
if (reset) {
|
if (reset) {
|
||||||
setProjects(parsedData);
|
setProjects(parsedData);
|
||||||
|
calculateAverage(parsedData);
|
||||||
setTotalCount(parsedData.length);
|
setTotalCount(parsedData.length);
|
||||||
} else {
|
} else {
|
||||||
setProjects((prev) => [...prev, ...parsedData]);
|
setProjects((prev) => [...prev, ...parsedData]);
|
||||||
|
|
@ -331,6 +345,7 @@ export function DigitalInnovationPage() {
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
setLoadingMore(false);
|
setLoadingMore(false);
|
||||||
|
|
||||||
fetchingRef.current = false;
|
fetchingRef.current = false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -385,6 +400,8 @@ export function DigitalInnovationPage() {
|
||||||
direction:
|
direction:
|
||||||
prev.field === field && prev.direction === "asc" ? "desc" : "asc",
|
prev.field === field && prev.direction === "asc" ? "desc" : "asc",
|
||||||
}));
|
}));
|
||||||
|
fetchTotalCount();
|
||||||
|
fetchStats();
|
||||||
setCurrentPage(1);
|
setCurrentPage(1);
|
||||||
setProjects([]);
|
setProjects([]);
|
||||||
setHasMore(true);
|
setHasMore(true);
|
||||||
|
|
@ -515,6 +532,30 @@ export function DigitalInnovationPage() {
|
||||||
}
|
}
|
||||||
}, [rating]);
|
}, [rating]);
|
||||||
|
|
||||||
|
const ststusColor = (status: projectStatus): any => {
|
||||||
|
let el = null;
|
||||||
|
switch (status) {
|
||||||
|
case projectStatus.contract:
|
||||||
|
el = "teal";
|
||||||
|
break;
|
||||||
|
case projectStatus.finish:
|
||||||
|
el = "info";
|
||||||
|
break;
|
||||||
|
case projectStatus.stop:
|
||||||
|
el = "warning";
|
||||||
|
break;
|
||||||
|
case projectStatus.inprogress:
|
||||||
|
el = "teal";
|
||||||
|
break;
|
||||||
|
case projectStatus.mafasa:
|
||||||
|
el = "destructive";
|
||||||
|
break;
|
||||||
|
case projectStatus.propozal:
|
||||||
|
el = "info";
|
||||||
|
}
|
||||||
|
return el;
|
||||||
|
};
|
||||||
|
|
||||||
const renderCellContent = (item: any, column: any) => {
|
const renderCellContent = (item: any, column: any) => {
|
||||||
const value = item[column.key as keyof ProcessInnovationData];
|
const value = item[column.key as keyof ProcessInnovationData];
|
||||||
|
|
||||||
|
|
@ -533,7 +574,7 @@ export function DigitalInnovationPage() {
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
size="sm"
|
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"
|
className="text-emerald-400 hover:text-emerald-300 hover:bg-emerald-500/20 p-2 h-auto cursor-pointer"
|
||||||
>
|
>
|
||||||
جزئیات بیشتر
|
جزئیات بیشتر
|
||||||
</Button>
|
</Button>
|
||||||
|
|
@ -554,15 +595,16 @@ export function DigitalInnovationPage() {
|
||||||
return <span className="font-medium text-white">{String(value)}</span>;
|
return <span className="font-medium text-white">{String(value)}</span>;
|
||||||
case "project_status":
|
case "project_status":
|
||||||
return (
|
return (
|
||||||
<Badge
|
<div className="flex items-center gap-1">
|
||||||
variant="outline"
|
<Badge
|
||||||
className="font-medium border-2"
|
variant={ststusColor(value)}
|
||||||
style={{
|
className="font-medium border-2 p-0 block w-2 h-2 rounded-full"
|
||||||
border: "none",
|
style={{
|
||||||
}}
|
border: "none",
|
||||||
>
|
}}
|
||||||
|
></Badge>
|
||||||
{String(value)}
|
{String(value)}
|
||||||
</Badge>
|
</div>
|
||||||
);
|
);
|
||||||
case "project_rating":
|
case "project_rating":
|
||||||
return (
|
return (
|
||||||
|
|
@ -583,6 +625,14 @@ export function DigitalInnovationPage() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const calculateAverage = (data: Array<ProcessInnovationData>) => {
|
||||||
|
let number = 0;
|
||||||
|
data.map(
|
||||||
|
(item: ProcessInnovationData) => (number = number + +item.project_rating)
|
||||||
|
);
|
||||||
|
setAvarage(number / data.length);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DashboardLayout title="نوآوری دیجیتال">
|
<DashboardLayout title="نوآوری دیجیتال">
|
||||||
<div className="flex flex-row gap-8 justify-between p-6 space-y-4 h-full">
|
<div className="flex flex-row gap-8 justify-between p-6 space-y-4 h-full">
|
||||||
|
|
@ -700,7 +750,7 @@ export function DigitalInnovationPage() {
|
||||||
<Card className="bg-transparent backdrop-blur-sm rounded-2xl overflow-hidden w-full h-max">
|
<Card className="bg-transparent backdrop-blur-sm rounded-2xl overflow-hidden w-full h-max">
|
||||||
<CardContent className="p-0">
|
<CardContent className="p-0">
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
<Table containerClassName="overflow-auto custom-scrollbar max-h-[calc(90vh-270px)]">
|
<Table containerClassName="overflow-auto custom-scrollbar h-[calc(90vh-270px)]">
|
||||||
<TableHeader>
|
<TableHeader>
|
||||||
<TableRow className="bg-[#3F415A]">
|
<TableRow className="bg-[#3F415A]">
|
||||||
{columns.map((column) => (
|
{columns.map((column) => (
|
||||||
|
|
@ -837,11 +887,7 @@ export function DigitalInnovationPage() {
|
||||||
میانگین امتیاز :
|
میانگین امتیاز :
|
||||||
</div>
|
</div>
|
||||||
<div className="font-bold">
|
<div className="font-bold">
|
||||||
{formatNumber(
|
{formatNumber(((avarage ?? 0) as number).toFixed?.(1) ?? 0)}
|
||||||
((stats.averageScore ?? 0) as number).toFixed?.(1) ??
|
|
||||||
stats.averageScore ??
|
|
||||||
0
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -876,7 +922,7 @@ export function DigitalInnovationPage() {
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<span className="text-sm text-gray-100">
|
<span className="text-sm text-gray-100">
|
||||||
شایستگی های کلیدی محدود
|
{dialogInfo?.digital_capability}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex justify-between">
|
<div className="flex justify-between">
|
||||||
|
|
@ -887,7 +933,7 @@ export function DigitalInnovationPage() {
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<span className="text-sm text-gray-100">
|
<span className="text-sm text-gray-100">
|
||||||
بدون تغییر کپی شده
|
{dialogInfo?.digital_competence}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex justify-between">
|
<div className="flex justify-between">
|
||||||
|
|
@ -901,15 +947,15 @@ export function DigitalInnovationPage() {
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<span className="text-sm text-gray-100">
|
<span className="text-sm text-gray-100">
|
||||||
دیجیتال کردن ارائه اطلاعات
|
{dialogInfo?.digital_puberty_elements}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="digitalAbilityDevelopment flex flex-col gap-10 border-l-2 border-l-gray-600 pr-5">
|
<div className="digitalAbilityDevelopment flex flex-col gap-10 border-l-2 border-l-gray-600 px-5">
|
||||||
<div className="flex flex-col gap-4">
|
<div className="flex flex-col gap-4">
|
||||||
<span className="text-sm font-bold">
|
<span className="text-md font-bold">
|
||||||
توسعه قابلیت های دیجیتال:{" "}
|
توسعه قابلیت های دیجیتال:{" "}
|
||||||
</span>
|
</span>
|
||||||
<div className="flex flex-col gap-2">
|
<div className="flex flex-col gap-2">
|
||||||
|
|
@ -918,28 +964,16 @@ export function DigitalInnovationPage() {
|
||||||
size={"1.2rem"}
|
size={"1.2rem"}
|
||||||
className="text-emerald-400"
|
className="text-emerald-400"
|
||||||
/>
|
/>
|
||||||
<span>قابلیت شماره یک </span>
|
<span className="text-sm">
|
||||||
</div>
|
{dialogInfo?.digital_capability}
|
||||||
<div className="flex gap-1.5">
|
</span>
|
||||||
<LoaderCircle
|
|
||||||
size={"1.2rem"}
|
|
||||||
className="text-emerald-400"
|
|
||||||
/>
|
|
||||||
<span>قابلیت شماره یک </span>
|
|
||||||
</div>
|
|
||||||
<div className="flex gap-1.5">
|
|
||||||
<LoaderCircle
|
|
||||||
size={"1.2rem"}
|
|
||||||
className="text-emerald-400"
|
|
||||||
/>
|
|
||||||
<span>قابلیت شماره یک </span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex flex-col gap-4">
|
<div className="flex flex-col gap-4">
|
||||||
<span className="text-sm font-bold">
|
<span className="text-md font-bold">
|
||||||
توسعه قابلیت های دیجیتال:{" "}
|
برنامه های عملیاتی مرتبط:
|
||||||
</span>
|
</span>
|
||||||
<div className="flex flex-col gap-2">
|
<div className="flex flex-col gap-2">
|
||||||
<div className="flex gap-1.5">
|
<div className="flex gap-1.5">
|
||||||
|
|
@ -947,27 +981,15 @@ export function DigitalInnovationPage() {
|
||||||
size={"1.2rem"}
|
size={"1.2rem"}
|
||||||
className="text-emerald-400"
|
className="text-emerald-400"
|
||||||
/>
|
/>
|
||||||
<span>قابلیت شماره یک </span>
|
<span className="text-sm">
|
||||||
</div>
|
{dialogInfo?.operational_plan}
|
||||||
<div className="flex gap-1.5">
|
</span>
|
||||||
<LoaderCircle
|
|
||||||
size={"1.2rem"}
|
|
||||||
className="text-emerald-400"
|
|
||||||
/>
|
|
||||||
<span>قابلیت شماره یک </span>
|
|
||||||
</div>
|
|
||||||
<div className="flex gap-1.5">
|
|
||||||
<LoaderCircle
|
|
||||||
size={"1.2rem"}
|
|
||||||
className="text-emerald-400"
|
|
||||||
/>
|
|
||||||
<span>قابلیت شماره یک </span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col gap-4">
|
<div className="flex flex-col gap-4">
|
||||||
<span className="text-sm font-bold">
|
<span className="text-md font-bold">
|
||||||
توسعه قابلیت های دیجیتال:{" "}
|
استراتژی های مورد نظر:
|
||||||
</span>
|
</span>
|
||||||
<div className="flex flex-col gap-2">
|
<div className="flex flex-col gap-2">
|
||||||
<div className="flex gap-1.5">
|
<div className="flex gap-1.5">
|
||||||
|
|
@ -975,22 +997,24 @@ export function DigitalInnovationPage() {
|
||||||
size={"1.2rem"}
|
size={"1.2rem"}
|
||||||
className="text-emerald-400"
|
className="text-emerald-400"
|
||||||
/>
|
/>
|
||||||
<span>قابلیت شماره یک </span>
|
<span className="text-sm">
|
||||||
|
{dialogInfo?.desired_strategy}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex gap-1.5">
|
{/* <div className="flex gap-1.5">
|
||||||
<LoaderCircle
|
<LoaderCircle
|
||||||
size={"1.2rem"}
|
size={"1.2rem"}
|
||||||
className="text-emerald-400"
|
className="text-emerald-400"
|
||||||
/>
|
/>
|
||||||
<span>قابلیت شماره یک </span>
|
<span>قابلیت شماره یک </span>
|
||||||
</div>
|
</div> */}
|
||||||
<div className="flex gap-1.5">
|
{/* <div className="flex gap-1.5">
|
||||||
<LoaderCircle
|
<LoaderCircle
|
||||||
size={"1.2rem"}
|
size={"1.2rem"}
|
||||||
className="text-emerald-400"
|
className="text-emerald-400"
|
||||||
/>
|
/>
|
||||||
<span>قابلیت شماره یک </span>
|
<span>قابلیت شماره یک </span>
|
||||||
</div>
|
</div> */}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1004,7 +1028,14 @@ export function DigitalInnovationPage() {
|
||||||
<div className="content p-4 flex flex-row-reverse gap-10 justify-center items-center">
|
<div className="content p-4 flex flex-row-reverse gap-10 justify-center items-center">
|
||||||
<div className="flex flex-col gap-1">
|
<div className="flex flex-col gap-1">
|
||||||
<span className="text-emerald-400 font-bold text-3xl">
|
<span className="text-emerald-400 font-bold text-3xl">
|
||||||
10%
|
%{" "}
|
||||||
|
{formatNumber(
|
||||||
|
(
|
||||||
|
Math.round(
|
||||||
|
dialogInfo?.reduce_costs_percent! * 100
|
||||||
|
) / 100
|
||||||
|
).toFixed(2)
|
||||||
|
)}
|
||||||
</span>
|
</span>
|
||||||
<span className="text-gray-500 text-sm font-normal">
|
<span className="text-gray-500 text-sm font-normal">
|
||||||
درصد به کل هزینه ها
|
درصد به کل هزینه ها
|
||||||
|
|
@ -1013,7 +1044,7 @@ export function DigitalInnovationPage() {
|
||||||
<b className="w-0.5 h-9 bg-gray-600 rotate-[35deg] rounded-full" />
|
<b className="w-0.5 h-9 bg-gray-600 rotate-[35deg] rounded-full" />
|
||||||
<div className="flex flex-col gap-1">
|
<div className="flex flex-col gap-1">
|
||||||
<span className="text-emerald-400 text-3xl font-bold">
|
<span className="text-emerald-400 text-3xl font-bold">
|
||||||
۱۰,۲۳۰
|
{formatNumber(+dialogInfo?.innovation_cost_reduction!)}
|
||||||
</span>
|
</span>
|
||||||
<span className="text-gray-500 text-sm font-normal">
|
<span className="text-gray-500 text-sm font-normal">
|
||||||
میلیون ریال
|
میلیون ریال
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ const Table = React.forwardRef<HTMLTableElement, TableProps>(
|
||||||
<div className={cn("relative w-full", containerClassName)}>
|
<div className={cn("relative w-full", containerClassName)}>
|
||||||
<table
|
<table
|
||||||
ref={ref}
|
ref={ref}
|
||||||
className={cn("w-full caption-bottom text-sm", className)}
|
className={cn("w-full caption-bottom text-sm h-full", className)}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user