feat/green-innovation (#6)

Co-authored-by: MehrdadAdabi <126083584+mehrdadAdabi@users.noreply.github.com>
Co-authored-by: mehrdad_adabi <mehrdadadabi29@gmail.com>
Co-authored-by: mehrdad <admehrdad148113@gmail.com>
Reviewed-on: https://git.pelekan.org/Saeed0920/inogen/pulls/6
Co-authored-by: Saeed Abadiyan <sd.eed1381@gmail.com>
Co-committed-by: Saeed Abadiyan <sd.eed1381@gmail.com>
This commit is contained in:
Saeed AB 2025-08-30 16:34:15 +03:30 committed by Saeed AB
parent 8cce0a0580
commit 9dd0e623a9
6 changed files with 2224 additions and 7892 deletions

File diff suppressed because it is too large Load Diff

View File

@ -121,7 +121,7 @@ export function ProcessInnovationPage() {
direction: "asc",
});
const [selectedProjects, setSelectedProjects] = useState<Set<string>>(
new Set(),
new Set()
);
const [detailsDialogOpen, setDetailsDialogOpen] = useState(false);
const [selectedProjectDetails, setSelectedProjectDetails] =
@ -167,7 +167,7 @@ export function ProcessInnovationPage() {
title: "جلوگیری از توقفات تولید",
value: formatNumber(
stats.productionStopsPreventionSum.toFixed?.(1) ??
stats.productionStopsPreventionSum,
stats.productionStopsPreventionSum
),
description: "تن افزایش یافته",
icon: <CirclePause />,
@ -186,7 +186,7 @@ export function ProcessInnovationPage() {
id: "currency-reduction",
title: "کاهش ارز بری",
value: formatNumber(
stats.currencyReductionSum.toFixed?.(0) ?? stats.currencyReductionSum,
stats.currencyReductionSum.toFixed?.(0) ?? stats.currencyReductionSum
),
description: "دلار کاهش یافته",
icon: <DollarSign />,
@ -197,7 +197,7 @@ export function ProcessInnovationPage() {
title: "کاهش خرابی های پرتکرار",
value: formatNumber(
stats.frequentFailuresReductionSum.toFixed?.(1) ??
stats.frequentFailuresReductionSum,
stats.frequentFailuresReductionSum
),
description: "مجموع درصد کاهش خرابی",
icon: <Wrench />,
@ -400,7 +400,7 @@ export function ProcessInnovationPage() {
if (typeof payload === "string") {
try {
payload = JSON.parse(payload);
} catch { }
} catch {}
}
const parseNum = (v: unknown): number => {
@ -418,22 +418,22 @@ export function ProcessInnovationPage() {
totalProjects: parseNum(payload?.count_innovation_process_projects),
averageScore: parseNum(payload?.average_project_score),
productionStopsPreventionSum: parseNum(
payload?.sum_stopping_production,
payload?.sum_stopping_production
),
bottleneckRemovalCount: parseNum(payload?.count_throat_removal),
currencyReductionSum: parseNum(payload?.sum_reduction_value_currency),
frequentFailuresReductionSum: parseNum(
payload?.sum_reducing_breakdowns,
payload?.sum_reducing_breakdowns
),
percentProductionStops: parseNum(
payload?.percent_sum_stopping_production,
payload?.percent_sum_stopping_production
),
percentBottleneckRemoval: parseNum(payload?.percent_throat_removal),
percentCurrencyReduction: parseNum(
payload?.percent_reduction_value_currency,
payload?.percent_reduction_value_currency
),
percentFailuresReduction: parseNum(
payload?.percent_reducing_breakdowns,
payload?.percent_reducing_breakdowns
),
};
@ -573,73 +573,73 @@ export function ProcessInnovationPage() {
<div className="grid grid-cols-2 gap-3">
{loading || statsLoading
? // Loading skeleton for stats cards - matching new design
Array.from({ length: 4 }).map((_, index) => (
<Card
key={`skeleton-${index}`}
className="bg-[linear-gradient(to_bottom_left,#464861,50%,#111628)] backdrop-blur-sm rounded-2xl overflow-hidden"
>
<CardContent className="p-2">
<div className="flex flex-col justify-between gap-2">
<div className="flex justify-between items-center border-b-2 mx-4 border-gray-500/20">
<div
className="h-6 bg-gray-600 rounded animate-pulse"
style={{ width: "60%" }}
/>
<div className="p-3 bg-emerald-500/20 rounded-full w-fit">
<div className="w-6 h-6 bg-gray-600 rounded animate-pulse" />
Array.from({ length: 4 }).map((_, index) => (
<Card
key={`skeleton-${index}`}
className="bg-[linear-gradient(to_bottom_left,#464861,50%,#111628)] backdrop-blur-sm rounded-2xl overflow-hidden"
>
<CardContent className="p-2">
<div className="flex flex-col justify-between gap-2">
<div className="flex justify-between items-center border-b-2 mx-4 border-gray-500/20">
<div
className="h-6 bg-gray-600 rounded animate-pulse"
style={{ width: "60%" }}
/>
<div className="p-3 bg-emerald-500/20 rounded-full w-fit">
<div className="w-6 h-6 bg-gray-600 rounded animate-pulse" />
</div>
</div>
<div className="flex items-center justify-center flex-col p-1">
<div
className="h-8 bg-gray-600 rounded mb-1 animate-pulse"
style={{ width: "40%" }}
/>
<div
className="h-4 bg-gray-600 rounded animate-pulse"
style={{ width: "80%" }}
/>
</div>
</div>
<div className="flex items-center justify-center flex-col p-1">
<div
className="h-8 bg-gray-600 rounded mb-1 animate-pulse"
style={{ width: "40%" }}
/>
<div
className="h-4 bg-gray-600 rounded animate-pulse"
style={{ width: "80%" }}
/>
</div>
</div>
</CardContent>
</Card>
))
</CardContent>
</Card>
))
: statsCards.map((card) => (
<Card
key={card.id}
className="bg-[linear-gradient(to_bottom_left,#464861,50%,#111628)] backdrop-blur-sm border-gray-700/50"
>
<CardContent className="p-2">
<div className="flex flex-col justify-between gap-2">
<div className="flex justify-between items-center border-b-2 mx-4 border-gray-500/20">
<h3 className="text-lg font-bold text-white font-persian">
{card.title}
</h3>
<div
className={`p-3 gird placeitems-center rounded-full w-fit `}
>
{card.icon}
<Card
key={card.id}
className="bg-[linear-gradient(to_bottom_left,#464861,50%,#111628)] backdrop-blur-sm border-gray-700/50"
>
<CardContent className="p-2">
<div className="flex flex-col justify-between gap-2">
<div className="flex justify-between items-center border-b-2 mx-4 border-gray-500/20">
<h3 className="text-lg font-bold text-white font-persian">
{card.title}
</h3>
<div
className={`p-3 gird placeitems-center rounded-full w-fit `}
>
{card.icon}
</div>
</div>
<div className="flex items-center justify-center flex-col p-1">
<p
className={`text-3xl font-bold ${card.color} mb-1`}
>
{card.value}
</p>
<p className="text-sm text-gray-300 font-persian">
{card.description}
</p>
</div>
</div>
<div className="flex items-center justify-center flex-col p-1">
<p
className={`text-3xl font-bold ${card.color} mb-1`}
>
{card.value}
</p>
<p className="text-sm text-gray-300 font-persian">
{card.description}
</p>
</div>
</div>
</CardContent>
</Card>
))}
</CardContent>
</Card>
))}
</div>
</div>
{/* Process Impacts Chart */}
<Card className="bg-[linear-gradient(to_bottom_left,#464861,50%,#111628)] backdrop-blur-sm rounded-2xl w-full overflow-hidden">
<CardContent >
<CardContent>
<CustomBarChart
title="تاثیرات فرآیندی به صورت درصد مقایسه ای"
loading={statsLoading}
@ -840,8 +840,8 @@ export function ProcessInnovationPage() {
<div className="font-bold">
{formatNumber(
((stats.averageScore ?? 0) as number).toFixed?.(1) ??
stats.averageScore ??
0,
stats.averageScore ??
0
)}
</div>
</div>
@ -881,9 +881,9 @@ export function ProcessInnovationPage() {
<span className="text-white font-bold font-persian">
{selectedProjectDetails?.start_date
? moment(
selectedProjectDetails?.start_date,
"YYYY-MM-DD",
).format("YYYY/MM/DD")
selectedProjectDetails?.start_date,
"YYYY-MM-DD"
).format("YYYY/MM/DD")
: "-"}
</span>
</div>
@ -896,9 +896,9 @@ export function ProcessInnovationPage() {
<span className="text-white font-bold font-persian">
{selectedProjectDetails?.done_date
? moment(
selectedProjectDetails?.done_date,
"YYYY-MM-DD",
).format("YYYY/MM/DD")
selectedProjectDetails?.done_date,
"YYYY-MM-DD"
).format("YYYY/MM/DD")
: "-"}
</span>
</div>
@ -913,9 +913,9 @@ export function ProcessInnovationPage() {
Number(
selectedProjectDetails?.approved_budget.replaceAll(
",",
"",
),
),
""
)
)
) || "-"}
</span>
</div>

View File

@ -8,10 +8,18 @@ export default [
"dashboard/innovation-basket/process-innovation",
"routes/innovation-basket.process-innovation.tsx"
),
route(
"dashboard/innovation-basket/green-innovation",
"routes/green-innovation.tsx"
),
route(
"/dashboard/innovation-basket/digital-innovation",
"routes/digital-innovation-page.tsx"
),
route(
"dashboard/innovation-basket/green-innovation",
"routes/green-innovation.tsx"
),
route("projects", "routes/projects.tsx"),
route("dashboard/ecosystem", "routes/ecosystem.tsx"),
route("404", "routes/404.tsx"),

View File

@ -0,0 +1,17 @@
import { ProtectedRoute } from "~/components/auth/protected-route";
import GreenInnovationPage from "~/components/dashboard/project-management/green-innovation-page";
export function meta() {
return [
{ title: "نوآوری در فرآیند - سیستم مدیریت فناوری و نوآوری" },
{ name: "description", content: "مدیریت پروژه‌های نوآوری در فرآیند" },
];
}
export default function GreenInnovation() {
return (
<ProtectedRoute requireAuth={true}>
<GreenInnovationPage />
</ProtectedRoute>
);
}

6859
package-lock.json generated

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff