From 6fdfe83b1edda6a11a0a6c42aa48ba216ab3bbc4 Mon Sep 17 00:00:00 2001 From: MehrdadAdabi <126083584+mehrdadAdabi@users.noreply.github.com> Date: Sun, 14 Sep 2025 16:07:30 +0330 Subject: [PATCH 1/5] feat:add redirect link to bpms --- app/components/dashboard/header.tsx | 30 +++++++++++++---- app/components/dashboard/layout.tsx | 6 +++- app/components/dashboard/sidebar.tsx | 50 +++++++++++++++------------- 3 files changed, 55 insertions(+), 31 deletions(-) diff --git a/app/components/dashboard/header.tsx b/app/components/dashboard/header.tsx index 32c7fb0..16e955b 100644 --- a/app/components/dashboard/header.tsx +++ b/app/components/dashboard/header.tsx @@ -5,17 +5,16 @@ import { cn } from "~/lib/utils"; import { Button } from "~/components/ui/button"; import { PanelLeft, - Search, - Bell, + Settings, User, - Moon, - Sun, + Menu, ChevronDown, - Globe, - HelpCircle, + Server, + } from "lucide-react"; +import apiService from "~/lib/api"; interface HeaderProps { onToggleSidebar?: () => void; @@ -32,6 +31,18 @@ export function Header({ const [isProfileMenuOpen, setIsProfileMenuOpen] = useState(false); const [isNotificationOpen, setIsNotificationOpen] = useState(false); + const redirectHandler = async () => { + try { + const getData = await apiService.post('/GenerateSsoCode') + const url = `http://localhost:3000/redirect/${getData.data}`; + // const url = `https://inogen-bpms.pelekan.org/redirect/${getData.data}`; + + window.open(url, "_blank"); + } catch (error) { + console.log(error); + } + } + return (
تنظیمات + + )} diff --git a/app/components/dashboard/layout.tsx b/app/components/dashboard/layout.tsx index 0d12e7f..adcbb16 100644 --- a/app/components/dashboard/layout.tsx +++ b/app/components/dashboard/layout.tsx @@ -3,6 +3,7 @@ import { cn } from "~/lib/utils"; import { Sidebar } from "./sidebar"; import { Header } from "./header"; import { StrategicAlignmentPopup } from "./strategic-alignment-popup"; +import apiService from "~/lib/api"; interface DashboardLayoutProps { children: React.ReactNode; @@ -27,10 +28,12 @@ export function DashboardLayout({ setIsMobileSidebarOpen(!isMobileSidebarOpen); }; + + return (
{/* Gradient overlay */}
@@ -58,6 +61,7 @@ export function DashboardLayout({ onToggleCollapse={toggleSidebarCollapse} className="h-full flex-shrink-0 relative z-10" onStrategicAlignmentClick={() => setIsStrategicAlignmentPopupOpen(true)} + />
diff --git a/app/components/dashboard/sidebar.tsx b/app/components/dashboard/sidebar.tsx index 4a90072..8f23cbb 100644 --- a/app/components/dashboard/sidebar.tsx +++ b/app/components/dashboard/sidebar.tsx @@ -15,6 +15,7 @@ import { Settings, Star, Workflow, + DiscAlbum } from "lucide-react"; import React, { useState } from "react"; import { Link, useLocation } from "react-router"; @@ -38,7 +39,7 @@ interface MenuItem { } const menuItems: MenuItem[] = [ - + { id: "dashboard", label: "صفحه اصلی", @@ -106,12 +107,13 @@ const menuItems: MenuItem[] = [ icon: Star, href: "/dashboard/top-innovations", }, - { + { id: "strategic-alignment", label: "میزان انطباق راهبردی", icon: null, href: "#", // This is not a route, it opens a popup }, + ]; const bottomMenuItems: MenuItem[] = [ @@ -214,29 +216,29 @@ export function Sidebar({ } }; - if (item.id === "strategic-alignment") { -return ( - -) +
+ + ) - } + } return (
@@ -292,10 +294,10 @@ return ( "w-full text-right", // Disable pointer cursor when child is active (cannot collapse) item.children && - item.children.some( - (child) => child.href && location.pathname === child.href - ) && - "cursor-not-allowed" + item.children.some( + (child) => child.href && location.pathname === child.href + ) && + "cursor-not-allowed" )} onClick={handleClick} > From 1b38e78ebdff390b92886f06650cf6017d05ad3d Mon Sep 17 00:00:00 2001 From: MehrdadAdabi <126083584+mehrdadAdabi@users.noreply.github.com> Date: Sun, 14 Sep 2025 17:25:30 +0330 Subject: [PATCH 2/5] fix: change redirect button postion in ui --- app/components/dashboard/header.tsx | 62 ++++++++++++------------ package-lock.json | 73 +++++++++++++++++++++++++++++ 2 files changed, 105 insertions(+), 30 deletions(-) diff --git a/app/components/dashboard/header.tsx b/app/components/dashboard/header.tsx index 16e955b..594821f 100644 --- a/app/components/dashboard/header.tsx +++ b/app/components/dashboard/header.tsx @@ -34,9 +34,8 @@ export function Header({ const redirectHandler = async () => { try { const getData = await apiService.post('/GenerateSsoCode') - const url = `http://localhost:3000/redirect/${getData.data}`; - // const url = `https://inogen-bpms.pelekan.org/redirect/${getData.data}`; - + // const url = `http://localhost:3000/redirect/${getData.data}`; + const url = `https://inogen-bpms.pelekan.org/redirect/${getData.data}`; window.open(url, "_blank"); } catch (error) { console.log(error); @@ -74,29 +73,39 @@ export function Header({
{/* User Menu */}
- +
+ + + + +
{/* Profile Dropdown */} {isProfileMenuOpen && ( -
+
{user?.name} {user?.family} @@ -122,13 +131,6 @@ export function Header({ تنظیمات - -
)} diff --git a/package-lock.json b/package-lock.json index 4340ade..35a0092 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,10 +10,12 @@ "@radix-ui/react-dialog": "^1.1.14", "@radix-ui/react-dropdown-menu": "^2.1.15", "@radix-ui/react-label": "^2.0.2", + "@radix-ui/react-popover": "^1.1.15", "@radix-ui/react-progress": "^1.1.7", "@radix-ui/react-select": "^2.2.5", "@radix-ui/react-slot": "^1.0.2", "@radix-ui/react-tabs": "^1.1.13", + "@radix-ui/react-tooltip": "^1.2.8", "@react-router/node": "^7.7.0", "@react-router/serve": "^7.7.1", "@types/d3": "^7.4.3", @@ -967,6 +969,43 @@ } } }, + "node_modules/@radix-ui/react-popover": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.1.15.tgz", + "integrity": "sha512-kr0X2+6Yy/vJzLYJUPCZEc8SfQcf+1COFoAqauJm74umQhta9M7lNJHP7QQS3vkvcGLQUbWpMzwrXYwrYztHKA==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-dismissable-layer": "1.1.11", + "@radix-ui/react-focus-guards": "1.1.3", + "@radix-ui/react-focus-scope": "1.1.7", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-popper": "1.2.8", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.6.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-popper": { "version": "1.2.8", "license": "MIT", @@ -1202,6 +1241,40 @@ } } }, + "node_modules/@radix-ui/react-tooltip": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.2.8.tgz", + "integrity": "sha512-tY7sVt1yL9ozIxvmbtN5qtmH2krXcBCfjEiCgKGLqunJHvgvZG2Pcl2oQ3kbcZARb1BGEHdkLzcYGO8ynVlieg==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-dismissable-layer": "1.1.11", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-popper": "1.2.8", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-visually-hidden": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-use-callback-ref": { "version": "1.1.1", "license": "MIT", From e3431533ca9b06a77a6d668cf9b48fedba6bc8ec Mon Sep 17 00:00:00 2001 From: MehrdadAdabi <126083584+mehrdadAdabi@users.noreply.github.com> Date: Mon, 15 Sep 2025 22:34:00 +0330 Subject: [PATCH 3/5] fix:change header styles --- app/components/dashboard/header.tsx | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/app/components/dashboard/header.tsx b/app/components/dashboard/header.tsx index 594821f..c6cf7f9 100644 --- a/app/components/dashboard/header.tsx +++ b/app/components/dashboard/header.tsx @@ -34,8 +34,8 @@ export function Header({ const redirectHandler = async () => { try { const getData = await apiService.post('/GenerateSsoCode') - // const url = `http://localhost:3000/redirect/${getData.data}`; - const url = `https://inogen-bpms.pelekan.org/redirect/${getData.data}`; + const url = `http://localhost:3000/redirect/${getData.data}`; + // const url = `https://inogen-bpms.pelekan.org/redirect/${getData.data}`; window.open(url, "_blank"); } catch (error) { console.log(error); @@ -75,6 +75,13 @@ export function Header({
+ { + user?.id === 2041 && + } - -
{/* Profile Dropdown */} {isProfileMenuOpen && ( -
+
{user?.name} {user?.family} From 137882fcb34a0791a6109bcef7cecfe8f757c93d Mon Sep 17 00:00:00 2001 From: saeed0920 Date: Tue, 16 Sep 2025 22:08:39 +0330 Subject: [PATCH 4/5] fix the api to handle the token expire things (#11) fix the api token expire time! Reviewed-on: https://git.pelekan.org/Saeed0920/inogen/pulls/11 Co-authored-by: saeed0920 Co-committed-by: saeed0920 --- app/lib/api.ts | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/app/lib/api.ts b/app/lib/api.ts index b26b23c..062c434 100644 --- a/app/lib/api.ts +++ b/app/lib/api.ts @@ -39,6 +39,19 @@ class ApiService { this.token = null; } + private handleSessionExpired(message?: string) { + this.clearToken(); + localStorage.removeItem("auth_token"); + localStorage.removeItem("auth_user"); + try { + sessionStorage.setItem("sessionExpired", "1"); + } catch {} + if (message) { + toast.error(message); + } + window.location.href = "/login"; + } + private async request( endpoint: string, options: RequestInit = {}, @@ -66,6 +79,11 @@ class ApiService { const response = await fetch(url, config); const data: ApiResponse = await response.json(); + if (data.errorCode === 301) { + this.handleSessionExpired("نشست شما منقضی شده است. لطفا دوباره وارد شوید."); + throw new Error(data.message || "Session expired"); + } + // Handle different response states if (!response.ok) { throw new Error( @@ -91,13 +109,7 @@ class ApiService { // Handle authentication errors if (error instanceof Error && error.message.includes("401")) { - this.clearToken(); - localStorage.removeItem("auth_token"); - localStorage.removeItem("auth_user"); - try { - sessionStorage.setItem("sessionExpired", "1"); - } catch {} - window.location.href = "/login"; + this.handleSessionExpired(); throw error; } @@ -128,6 +140,11 @@ class ApiService { const response = await fetch(fullUrl, config); const apiData: ApiResponse = await response.json(); + if (apiData.errorCode === 301) { + this.handleSessionExpired("نشست شما منقضی شده است. لطفا دوباره وارد شوید."); + throw new Error(apiData.message || "Session expired"); + } + if (!response.ok) { throw new Error(apiData?.message || `HTTP error! status: ${response.status}`); } From 8bdc533b0ba0a446d6c3c384753430167b37f92d Mon Sep 17 00:00:00 2001 From: saeed0920 Date: Wed, 17 Sep 2025 12:22:11 +0330 Subject: [PATCH 5/5] fix the bug in sidebar --- app/components/dashboard/sidebar.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/components/dashboard/sidebar.tsx b/app/components/dashboard/sidebar.tsx index 4148e01..75fc0ac 100644 --- a/app/components/dashboard/sidebar.tsx +++ b/app/components/dashboard/sidebar.tsx @@ -208,6 +208,7 @@ export function Sidebar({ const handleClick = () => { if (item.id === "strategic-alignment") { + console.log("test") onStrategicAlignmentClick?.(); } else if (item.id === "logout") { logout(); @@ -223,6 +224,7 @@ export function Sidebar({ className={cn( "flex items-center justify-center w-full px-2 rounded-lg mt-4 transition-all duration-200 group", )} + onClick={handleClick} >