diff --git a/app/components/auth/login-form.tsx b/app/components/auth/login-form.tsx index 64375ba..2b177d8 100644 --- a/app/components/auth/login-form.tsx +++ b/app/components/auth/login-form.tsx @@ -212,7 +212,9 @@ export function LoginForm({ onSuccess }: LoginFormProps) { {/* Right Side - Branding */} } diff --git a/app/components/auth/login-layout.tsx b/app/components/auth/login-layout.tsx index d6ec2f6..9f76eba 100644 --- a/app/components/auth/login-layout.tsx +++ b/app/components/auth/login-layout.tsx @@ -1,6 +1,7 @@ import React from "react"; import { cn } from "~/lib/utils"; + interface LoginLayoutProps { children: React.ReactNode; className?: string; @@ -106,14 +107,25 @@ export function LoginBranding({ }: LoginBrandingProps) { return ( <> - {/* Top Logo */} -
-
-
- -
-
-
+
+
+
+ Brand Logo { + e.target.style.display = 'none'; + console.log('Image failed to load'); + }} + /> +
+
+
+ + + + {/* Bottom Section */}
diff --git a/app/components/dashboard/d3-image-info.tsx b/app/components/dashboard/d3-image-info.tsx index 72af552..572ae7a 100644 --- a/app/components/dashboard/d3-image-info.tsx +++ b/app/components/dashboard/d3-image-info.tsx @@ -1,3 +1,4 @@ +//این فایل مخصوص //شماتیک آپادانا import React from "react"; diff --git a/app/components/dashboard/d3-image-info1.tsx b/app/components/dashboard/d3-image-info1.tsx index 871248f..ab8e014 100644 --- a/app/components/dashboard/d3-image-info1.tsx +++ b/app/components/dashboard/d3-image-info1.tsx @@ -1,4 +1,4 @@ - +//این فایل مخصوص //شماتیک بندر امام import React from "react"; import { formatNumber } from "~/lib/utils"; diff --git a/app/components/dashboard/d3-image-info3.tsx b/app/components/dashboard/d3-image-info3.tsx new file mode 100644 index 0000000..2083b67 --- /dev/null +++ b/app/components/dashboard/d3-image-info3.tsx @@ -0,0 +1,211 @@ +//این فایل مخصوص +//شماتیک نوری + +import React from "react"; +import { formatNumber } from "~/lib/utils"; + +export type CompanyInfo = { + id: string; + imageUrl: string; + name: string; + costReduction: number; + revenue?: number; + capacity?: number; + costI: number; + capacityI: number; + revenueI: number; + cost: number | string; +}; + +export type D3ImageInfoProps = { + companies: CompanyInfo[]; + width?: number; + height?: number; +}; + +const InfoBox = ({ company, style }: { company: CompanyInfo; style: any }) => { + // const hideCapacity = company.name === "واحد 300"; // اگر واحد 300 بود ظرفیت مخفی شود + const hideCapacity = false; + return ( +
+
+
+
درآمد:
+
{formatNumber(company?.revenue || 0)}
+
میلیون ریال
+
+
+
هزینه:
+ {hideCapacity ? ( +
{formatNumber(company?.cost || 0)}
+ ) : ( +
{formatNumber(company?.cost || 0)}
+ )} +
میلیون ریال
+
+ {!hideCapacity && ( +
+
ظرفیت:
+
{formatNumber(company?.capacity || 0)}
+
تن در سال
+
+ )} +
+
+ ); +}; + +export function D3ImageInfo({ companies }: D3ImageInfoProps) { + // واحدهای جدید - 4 واحد + const sample = [ + { id: "واحد 100", name: "واحد 100", imageUrl: "/abniro.png" }, + { id: "واحد 200", name: "واحد 200", imageUrl: "/besparan.png" }, + { id: "واحد 300", name: "واحد 300", imageUrl: "/khwarazmi.png" }, + { id: "واحد 400", name: "واحد 400", imageUrl: "/faravash1.png" } + ]; + + + + const merged = sample.map(company => { + const found = companies.find(item => item.id === company.id); + return found + ? found + : { ...company, cost: 0, capacity: 0, revenue: 0, costReduction: 0, costI: 0, capacityI: 0, revenueI: 0 }; + }); + + const displayCompanies = merged; + console.log(displayCompanies); + + // موقعیت‌های جدید برای چیدمان لوزی شکل (3 ردیف - 1-2-1) + // گرید 5x4 نگه داشته شده اما موقعیت‌ها تغییر کرده + const gridPositions = [ + { col: 2, row: 1, colI: 1, rowI: 1, name: "واحد 100" }, // ردیف اول - ستون اول + { col: 4, row: 1, colI: 5, rowI: 1, name: "واحد 200" }, // ردیف اول - ستون دوم + { col: 2, row: 3, colI: 1, rowI: 3, name: "واحد 300" }, // ردیف دوم - ستون اول + { col: 4, row: 3, colI: 5, rowI: 3, name: "واحد 400" }, // ردیف دوم - ستون دوم + ]; + + return ( +
+
+ {displayCompanies.map((company, index) => { + const gp = gridPositions.find(v => v.name === company.name); + return ( + +
+
+ {company.name} +
+ {company.name} +
+ +
+ ); + })} +
+ + +
+ ); +} \ No newline at end of file diff --git a/app/components/dashboard/dashboard-home.tsx b/app/components/dashboard/dashboard-home.tsx index 1599c58..d3fcc42 100644 --- a/app/components/dashboard/dashboard-home.tsx +++ b/app/components/dashboard/dashboard-home.tsx @@ -641,6 +641,7 @@ export function DashboardHome() {
{ // const imageMap: Record = { @@ -662,7 +663,14 @@ export function DashboardHome() { "واحد 400": "/faravash1.png" }; - + //پتروشیمی نوری + // companies={companyChartData.map((item) => { + // const imageMap: Record = { + // "واحد 100": "/abniro.png" , + // "واحد 200": "/besparan.png" , + // "واحد 300": "/khwarazmi.png" , + // "واحد 400": "/faravash1.png" + // }; diff --git a/app/components/dashboard/header.tsx b/app/components/dashboard/header.tsx index d32a18c..822d576 100644 --- a/app/components/dashboard/header.tsx +++ b/app/components/dashboard/header.tsx @@ -233,7 +233,14 @@ export function Header({ const redirectHandler = async () => { try { const getData = await apiService.post("/GenerateSsoCode"); - const url = `https://inogen-bpms.pelekan.org/redirect/${getData.data}`; + + //بندر امام + // const url = `https://inogen-bpms.pelekan.org/redirect/${getData.data}`; + //آپادانا + const url = `https://APADANA-IATM-bpms.pelekan.org/redirect/${getData.data}`; + //نوری + // const url = `https://NOPC-IATM-bpms.pelekan.org/redirect/${getData.data}`; + window.open(url, "_blank"); } catch (error) { console.log(error); diff --git a/app/components/ecosystem/network-graph.tsx b/app/components/ecosystem/network-graph.tsx index b7be02b..4ac8263 100644 --- a/app/components/ecosystem/network-graph.tsx +++ b/app/components/ecosystem/network-graph.tsx @@ -7,7 +7,13 @@ import { useAuth } from "../../contexts/auth-context"; import apiService from "../../lib/api"; const API_BASE_URL = - import.meta.env.VITE_API_URL || "https://inogen-back.pelekan.org/api"; +//بندر امام +// import.meta.env.VITE_API_URL || "https://inogen-back.pelekan.org/api"; +//آپادانا +import.meta.env.VITE_API_URL || "https://APADANA-IATM-back.pelekan.org/api"; +//نوری +// import.meta.env.VITE_API_URL || "https://NOPC-IATM-back.pelekan.org/api"; + export interface Node { id: string; @@ -143,7 +149,9 @@ export function NetworkGraph({ // نود مرکزی const centerNode: Node = { id: "center", - label: "پتروشیمی بندر امام", + // label: "پتروشیمی بندر امام", + // label: "پتروشیمی نوری", + label: "پتروشیمی آپادانا", category: "center", stageid: 0, isCenter: true, @@ -367,41 +375,90 @@ export function NetworkGraph({ nodeGroup.each(function (d) { const group = d3.select(this); - if (d.isCenter) { - const rect = group - .append("rect") - .attr("width", 200) - .attr("height", 80) - .attr("x", -100) // نصف عرض جدید منفی - .attr("y", -40) // نصف ارتفاع جدید منفی - .attr("rx", 8) - .attr("ry", 8) - .attr("fill", categoryToColor[d.category] || "#94A3B8") - .attr("stroke", "#FFFFFF") - .attr("stroke-width", 3) - .style("pointer-events", "none"); + // if (d.isCenter) { + // const rect = group + // .append("rect") + // .attr("width", 200) + // .attr("height", 80) + // .attr("x", -100) // نصف عرض جدید منفی + // .attr("y", -40) // نصف ارتفاع جدید منفی + // .attr("rx", 8) + // .attr("ry", 8) + // .attr("fill", categoryToColor[d.category] || "#94A3B8") + // .attr("stroke", "#FFFFFF") + // .attr("stroke-width", 3) + // .style("pointer-events", "none"); - if (d.imageUrl || d.isCenter) { - const pattern = defs - .append("pattern") - .attr("id", `image-${d.id}`) - .attr("x", 0) - .attr("y", 0) - .attr("width", 1) - .attr("height", 1); + // if (d.imageUrl || d.isCenter) { + // const pattern = defs + // .append("pattern") + // .attr("id", `image-${d.id}`) + // .attr("x", 0) + // .attr("y", 0) + // .attr("width", 1) + // .attr("height", 1); - pattern - .append("image") - .attr("x", 0) - .attr("y", 0) - .attr("width", 200) // ← هم‌اندازه با مستطیل - .attr("height", 80) - .attr("href", d.isCenter ? "/main-circle.png" : d.imageUrl) - .attr("preserveAspectRatio", "xMidYMid slice"); + // pattern + // .append("image") + // .attr("x", 0) + // .attr("y", 0) + // .attr("width", 200) // ← هم‌اندازه با مستطیل + // .attr("height", 80) + // .attr("href", d.isCenter ? "/main-circle.png" : d.imageUrl) + // .attr("preserveAspectRatio", "xMidYMid slice"); - rect.attr("fill", `url(#image-${d.id})`); - } - } else { + // rect.attr("fill", `url(#image-${d.id})`); + // } + // } + // راه حل ساده‌تر - ابعاد ثابت با حفظ نسبت +if (d.isCenter) { + + //آپادانا +const fixedWidth = 198; +const fixedHeight = 200; // یا می‌توانید براساس نسبت تصویر محاسبه کنید + +//بندر امام +// const fixedWidth = 100; +// const fixedHeight = 80; // یا می‌توانید براساس نسبت تصویر محاسبه کنید + +//نوری +// const fixedWidth = 100; +// const fixedHeight = 80; // یا می‌توانید براساس نسبت تصویر محاسبه کنید + + const rect = group + .append("rect") + .attr("width", fixedWidth) + .attr("height", fixedHeight) + .attr("x", -fixedWidth / 2) + .attr("y", -fixedHeight / 2) + .attr("rx", 8) + .attr("ry", 8) + .attr("fill", categoryToColor[d.category] || "#94A3B8") + .attr("stroke", "#FFFFFF") + .attr("stroke-width", 3) + .style("pointer-events", "none"); + + const pattern = defs + .append("pattern") + .attr("id", `image-${d.id}`) + .attr("x", 0) + .attr("y", 0) + .attr("width", 1) + .attr("height", 1); + + pattern + .append("image") + .attr("x", 0) + .attr("y", 0) + .attr("width", fixedWidth) + .attr("height", fixedHeight) + .attr("href", d.isCenter ? "/main-circle.png" : d.imageUrl) + .attr("preserveAspectRatio", "xMidYMid meet"); // حفظ نسبت تصویر + + rect.attr("fill", `url(#image-${d.id})`); + +} + else { const circle = group .append("circle") .attr("r", 25) @@ -441,16 +498,31 @@ export function NetworkGraph({ }); const labels = nodeGroup - .append("text") - .text((d) => d.label) - .attr("text-anchor", "middle") - .attr("dy", (d) => (d.isCenter ? 50 : 45)) - .attr("font-size", (d) => (d.isCenter ? "14px" : "12px")) - .attr("font-weight", "bold") - .attr("fill", "#F9FAFB") - .attr("stroke", "rgba(17, 24, 39, 0.95)") - .attr("stroke-width", 4) - .attr("paint-order", "stroke"); + .append("text") + .text((d) => d.label) + .attr("text-anchor", "middle") + .attr("dy", (d) => { + if (d.isCenter) { + + //آپادانا + const centerNodeHeight = 200; // ارتفاع نود مرکزی + + //بندر امام + // const centerNodeHeight = 80; // ارتفاع نود مرکزی + + //نوری + // const centerNodeHeight = 80; // ارتفاع نود مرکزی + + return centerNodeHeight / 2 + 20; // نصف ارتفاع + فاصله 20px + } + return 45; // برای نودهای دیگر + }) + .attr("font-size", (d) => (d.isCenter ? "14px" : "12px")) + .attr("font-weight", "bold") + .attr("fill", "#F9FAFB") + .attr("stroke", "rgba(17, 24, 39, 0.95)") + .attr("stroke-width", 4) + .attr("paint-order", "stroke"); nodeGroup .on("mouseenter", function (event, d) { diff --git a/app/lib/api.ts b/app/lib/api.ts index 062c434..13fc730 100644 --- a/app/lib/api.ts +++ b/app/lib/api.ts @@ -162,10 +162,24 @@ class ApiService { // Innovation process function call wrapper public async call(payload: any) { + //بندر امام const url = "https://inogen-back.pelekan.org/api/call"; + //آپادانا + const url = "https://APADANA-IATM-back.pelekan.org/api/call"; + //نوری + const url = "https://NOPC-IATM-back.pelekan.org/api/call"; return this.postAbsolute(url, payload); } + + const API_BASE_URL = + //بندر امام + // import.meta.env.VITE_API_URL || "https://inogen-bpms-back.pelekan.org/api"; + //آپادانا + import.meta.env.VITE_API_URL || "https://APADANA-IATM-back.pelekan.org/api"; + //نوری + // import.meta.env.VITE_API_URL || "https://NOPC-IATM-back.pelekan.org/api"; + // GET request public async get(endpoint: string): Promise> { return this.request(endpoint, { diff --git a/app/routes/ecosystem.tsx b/app/routes/ecosystem.tsx index 57e9cba..ff741c7 100644 --- a/app/routes/ecosystem.tsx +++ b/app/routes/ecosystem.tsx @@ -16,7 +16,14 @@ import type { Route } from "./+types/ecosystem"; // Get API base URL at module level to avoid process.env access in browser const API_BASE_URL = - import.meta.env.VITE_API_URL || "https://inogen-back.pelekan.org/api"; +//بندر امام +// import.meta.env.VITE_API_URL || "https://inogen-back.pelekan.org/api"; +//آپادانا +import.meta.env.VITE_API_URL || "https://APADANA-IATM-back.pelekan.org/api"; +//نوری +// import.meta.env.VITE_API_URL || "https://NOPC-IATM-back.pelekan.org/api"; + + // Import the CompanyDetails type import { Hexagon } from "lucide-react";