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:
parent
8cce0a0580
commit
9dd0e623a9
File diff suppressed because it is too large
Load Diff
|
|
@ -121,7 +121,7 @@ export function ProcessInnovationPage() {
|
||||||
direction: "asc",
|
direction: "asc",
|
||||||
});
|
});
|
||||||
const [selectedProjects, setSelectedProjects] = useState<Set<string>>(
|
const [selectedProjects, setSelectedProjects] = useState<Set<string>>(
|
||||||
new Set(),
|
new Set()
|
||||||
);
|
);
|
||||||
const [detailsDialogOpen, setDetailsDialogOpen] = useState(false);
|
const [detailsDialogOpen, setDetailsDialogOpen] = useState(false);
|
||||||
const [selectedProjectDetails, setSelectedProjectDetails] =
|
const [selectedProjectDetails, setSelectedProjectDetails] =
|
||||||
|
|
@ -167,7 +167,7 @@ export function ProcessInnovationPage() {
|
||||||
title: "جلوگیری از توقفات تولید",
|
title: "جلوگیری از توقفات تولید",
|
||||||
value: formatNumber(
|
value: formatNumber(
|
||||||
stats.productionStopsPreventionSum.toFixed?.(1) ??
|
stats.productionStopsPreventionSum.toFixed?.(1) ??
|
||||||
stats.productionStopsPreventionSum,
|
stats.productionStopsPreventionSum
|
||||||
),
|
),
|
||||||
description: "تن افزایش یافته",
|
description: "تن افزایش یافته",
|
||||||
icon: <CirclePause />,
|
icon: <CirclePause />,
|
||||||
|
|
@ -186,7 +186,7 @@ export function ProcessInnovationPage() {
|
||||||
id: "currency-reduction",
|
id: "currency-reduction",
|
||||||
title: "کاهش ارز بری",
|
title: "کاهش ارز بری",
|
||||||
value: formatNumber(
|
value: formatNumber(
|
||||||
stats.currencyReductionSum.toFixed?.(0) ?? stats.currencyReductionSum,
|
stats.currencyReductionSum.toFixed?.(0) ?? stats.currencyReductionSum
|
||||||
),
|
),
|
||||||
description: "دلار کاهش یافته",
|
description: "دلار کاهش یافته",
|
||||||
icon: <DollarSign />,
|
icon: <DollarSign />,
|
||||||
|
|
@ -197,7 +197,7 @@ export function ProcessInnovationPage() {
|
||||||
title: "کاهش خرابی های پرتکرار",
|
title: "کاهش خرابی های پرتکرار",
|
||||||
value: formatNumber(
|
value: formatNumber(
|
||||||
stats.frequentFailuresReductionSum.toFixed?.(1) ??
|
stats.frequentFailuresReductionSum.toFixed?.(1) ??
|
||||||
stats.frequentFailuresReductionSum,
|
stats.frequentFailuresReductionSum
|
||||||
),
|
),
|
||||||
description: "مجموع درصد کاهش خرابی",
|
description: "مجموع درصد کاهش خرابی",
|
||||||
icon: <Wrench />,
|
icon: <Wrench />,
|
||||||
|
|
@ -400,7 +400,7 @@ export function ProcessInnovationPage() {
|
||||||
if (typeof payload === "string") {
|
if (typeof payload === "string") {
|
||||||
try {
|
try {
|
||||||
payload = JSON.parse(payload);
|
payload = JSON.parse(payload);
|
||||||
} catch { }
|
} catch {}
|
||||||
}
|
}
|
||||||
|
|
||||||
const parseNum = (v: unknown): number => {
|
const parseNum = (v: unknown): number => {
|
||||||
|
|
@ -418,22 +418,22 @@ export function ProcessInnovationPage() {
|
||||||
totalProjects: parseNum(payload?.count_innovation_process_projects),
|
totalProjects: parseNum(payload?.count_innovation_process_projects),
|
||||||
averageScore: parseNum(payload?.average_project_score),
|
averageScore: parseNum(payload?.average_project_score),
|
||||||
productionStopsPreventionSum: parseNum(
|
productionStopsPreventionSum: parseNum(
|
||||||
payload?.sum_stopping_production,
|
payload?.sum_stopping_production
|
||||||
),
|
),
|
||||||
bottleneckRemovalCount: parseNum(payload?.count_throat_removal),
|
bottleneckRemovalCount: parseNum(payload?.count_throat_removal),
|
||||||
currencyReductionSum: parseNum(payload?.sum_reduction_value_currency),
|
currencyReductionSum: parseNum(payload?.sum_reduction_value_currency),
|
||||||
frequentFailuresReductionSum: parseNum(
|
frequentFailuresReductionSum: parseNum(
|
||||||
payload?.sum_reducing_breakdowns,
|
payload?.sum_reducing_breakdowns
|
||||||
),
|
),
|
||||||
percentProductionStops: parseNum(
|
percentProductionStops: parseNum(
|
||||||
payload?.percent_sum_stopping_production,
|
payload?.percent_sum_stopping_production
|
||||||
),
|
),
|
||||||
percentBottleneckRemoval: parseNum(payload?.percent_throat_removal),
|
percentBottleneckRemoval: parseNum(payload?.percent_throat_removal),
|
||||||
percentCurrencyReduction: parseNum(
|
percentCurrencyReduction: parseNum(
|
||||||
payload?.percent_reduction_value_currency,
|
payload?.percent_reduction_value_currency
|
||||||
),
|
),
|
||||||
percentFailuresReduction: parseNum(
|
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">
|
<div className="grid grid-cols-2 gap-3">
|
||||||
{loading || statsLoading
|
{loading || statsLoading
|
||||||
? // Loading skeleton for stats cards - matching new design
|
? // Loading skeleton for stats cards - matching new design
|
||||||
Array.from({ length: 4 }).map((_, index) => (
|
Array.from({ length: 4 }).map((_, index) => (
|
||||||
<Card
|
<Card
|
||||||
key={`skeleton-${index}`}
|
key={`skeleton-${index}`}
|
||||||
className="bg-[linear-gradient(to_bottom_left,#464861,50%,#111628)] backdrop-blur-sm rounded-2xl overflow-hidden"
|
className="bg-[linear-gradient(to_bottom_left,#464861,50%,#111628)] backdrop-blur-sm rounded-2xl overflow-hidden"
|
||||||
>
|
>
|
||||||
<CardContent className="p-2">
|
<CardContent className="p-2">
|
||||||
<div className="flex flex-col justify-between gap-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="flex justify-between items-center border-b-2 mx-4 border-gray-500/20">
|
||||||
<div
|
<div
|
||||||
className="h-6 bg-gray-600 rounded animate-pulse"
|
className="h-6 bg-gray-600 rounded animate-pulse"
|
||||||
style={{ width: "60%" }}
|
style={{ width: "60%" }}
|
||||||
/>
|
/>
|
||||||
<div className="p-3 bg-emerald-500/20 rounded-full w-fit">
|
<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 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>
|
</div>
|
||||||
<div className="flex items-center justify-center flex-col p-1">
|
</CardContent>
|
||||||
<div
|
</Card>
|
||||||
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>
|
|
||||||
))
|
|
||||||
: statsCards.map((card) => (
|
: statsCards.map((card) => (
|
||||||
<Card
|
<Card
|
||||||
key={card.id}
|
key={card.id}
|
||||||
className="bg-[linear-gradient(to_bottom_left,#464861,50%,#111628)] backdrop-blur-sm border-gray-700/50"
|
className="bg-[linear-gradient(to_bottom_left,#464861,50%,#111628)] backdrop-blur-sm border-gray-700/50"
|
||||||
>
|
>
|
||||||
<CardContent className="p-2">
|
<CardContent className="p-2">
|
||||||
<div className="flex flex-col justify-between gap-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="flex justify-between items-center border-b-2 mx-4 border-gray-500/20">
|
||||||
<h3 className="text-lg font-bold text-white font-persian">
|
<h3 className="text-lg font-bold text-white font-persian">
|
||||||
{card.title}
|
{card.title}
|
||||||
</h3>
|
</h3>
|
||||||
<div
|
<div
|
||||||
className={`p-3 gird placeitems-center rounded-full w-fit `}
|
className={`p-3 gird placeitems-center rounded-full w-fit `}
|
||||||
>
|
>
|
||||||
{card.icon}
|
{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>
|
</div>
|
||||||
<div className="flex items-center justify-center flex-col p-1">
|
</CardContent>
|
||||||
<p
|
</Card>
|
||||||
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>
|
|
||||||
))}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Process Impacts Chart */}
|
{/* Process Impacts Chart */}
|
||||||
<Card className="bg-[linear-gradient(to_bottom_left,#464861,50%,#111628)] backdrop-blur-sm rounded-2xl w-full overflow-hidden">
|
<Card className="bg-[linear-gradient(to_bottom_left,#464861,50%,#111628)] backdrop-blur-sm rounded-2xl w-full overflow-hidden">
|
||||||
<CardContent >
|
<CardContent>
|
||||||
<CustomBarChart
|
<CustomBarChart
|
||||||
title="تاثیرات فرآیندی به صورت درصد مقایسه ای"
|
title="تاثیرات فرآیندی به صورت درصد مقایسه ای"
|
||||||
loading={statsLoading}
|
loading={statsLoading}
|
||||||
|
|
@ -840,8 +840,8 @@ export function ProcessInnovationPage() {
|
||||||
<div className="font-bold">
|
<div className="font-bold">
|
||||||
{formatNumber(
|
{formatNumber(
|
||||||
((stats.averageScore ?? 0) as number).toFixed?.(1) ??
|
((stats.averageScore ?? 0) as number).toFixed?.(1) ??
|
||||||
stats.averageScore ??
|
stats.averageScore ??
|
||||||
0,
|
0
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -881,9 +881,9 @@ export function ProcessInnovationPage() {
|
||||||
<span className="text-white font-bold font-persian">
|
<span className="text-white font-bold font-persian">
|
||||||
{selectedProjectDetails?.start_date
|
{selectedProjectDetails?.start_date
|
||||||
? moment(
|
? moment(
|
||||||
selectedProjectDetails?.start_date,
|
selectedProjectDetails?.start_date,
|
||||||
"YYYY-MM-DD",
|
"YYYY-MM-DD"
|
||||||
).format("YYYY/MM/DD")
|
).format("YYYY/MM/DD")
|
||||||
: "-"}
|
: "-"}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -896,9 +896,9 @@ export function ProcessInnovationPage() {
|
||||||
<span className="text-white font-bold font-persian">
|
<span className="text-white font-bold font-persian">
|
||||||
{selectedProjectDetails?.done_date
|
{selectedProjectDetails?.done_date
|
||||||
? moment(
|
? moment(
|
||||||
selectedProjectDetails?.done_date,
|
selectedProjectDetails?.done_date,
|
||||||
"YYYY-MM-DD",
|
"YYYY-MM-DD"
|
||||||
).format("YYYY/MM/DD")
|
).format("YYYY/MM/DD")
|
||||||
: "-"}
|
: "-"}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -913,9 +913,9 @@ export function ProcessInnovationPage() {
|
||||||
Number(
|
Number(
|
||||||
selectedProjectDetails?.approved_budget.replaceAll(
|
selectedProjectDetails?.approved_budget.replaceAll(
|
||||||
",",
|
",",
|
||||||
"",
|
""
|
||||||
),
|
)
|
||||||
),
|
)
|
||||||
) || "-"}
|
) || "-"}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,18 @@ export default [
|
||||||
"dashboard/innovation-basket/process-innovation",
|
"dashboard/innovation-basket/process-innovation",
|
||||||
"routes/innovation-basket.process-innovation.tsx"
|
"routes/innovation-basket.process-innovation.tsx"
|
||||||
),
|
),
|
||||||
|
route(
|
||||||
|
"dashboard/innovation-basket/green-innovation",
|
||||||
|
"routes/green-innovation.tsx"
|
||||||
|
),
|
||||||
route(
|
route(
|
||||||
"/dashboard/innovation-basket/digital-innovation",
|
"/dashboard/innovation-basket/digital-innovation",
|
||||||
"routes/digital-innovation-page.tsx"
|
"routes/digital-innovation-page.tsx"
|
||||||
),
|
),
|
||||||
|
route(
|
||||||
|
"dashboard/innovation-basket/green-innovation",
|
||||||
|
"routes/green-innovation.tsx"
|
||||||
|
),
|
||||||
route("projects", "routes/projects.tsx"),
|
route("projects", "routes/projects.tsx"),
|
||||||
route("dashboard/ecosystem", "routes/ecosystem.tsx"),
|
route("dashboard/ecosystem", "routes/ecosystem.tsx"),
|
||||||
route("404", "routes/404.tsx"),
|
route("404", "routes/404.tsx"),
|
||||||
|
|
|
||||||
17
app/routes/green-innovation.tsx
Normal file
17
app/routes/green-innovation.tsx
Normal 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
6859
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
1917
pnpm-lock.yaml
1917
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user