From ec383c109f1c47845fe885ce1321598b1123e019 Mon Sep 17 00:00:00 2001 From: JaiPandey425 Date: Thu, 6 Nov 2025 17:01:59 +0530 Subject: [PATCH] logout error --- src/electron/api/axiosClient.ts | 37 +++++------ src/electron/ipc/ipcHandler.ts | 8 +++ src/electron/preload.ts | 4 ++ src/ui/layout/DashboardLayout.tsx | 101 ++++++++++++++++-------------- types.d.ts | 1 + 5 files changed, 87 insertions(+), 64 deletions(-) diff --git a/src/electron/api/axiosClient.ts b/src/electron/api/axiosClient.ts index 502cf47..9cc2209 100644 --- a/src/electron/api/axiosClient.ts +++ b/src/electron/api/axiosClient.ts @@ -5,34 +5,35 @@ import { getToken } from '../utils/tokenHelper.js'; const TOKEN_KEY = 'auth_token'; const api: AxiosInstance = axios.create({ - baseURL: 'https://api.example.com', // 🔁 your backend - timeout: 10000, + baseURL: 'https://wired-terminally-muskrat.ngrok-free.app/api/v1', // 🔁 your backend + timeout: 10000, }); // --- Request Interceptor --- api.interceptors.request.use( - async (config: AxiosRequestConfig) : Promise => { - const token = await getToken(TOKEN_KEY); - if (token && config.headers) { - config.headers.Authorization = `Bearer ${token}`; - } + async (config: AxiosRequestConfig): Promise => { + const token = await getToken(TOKEN_KEY); + if (token && config.headers) { + config.headers.token = token; + config.headers['ngrok-skip-browser-warning'] = 98098; + } - console.log(`[Axios] ${config.method?.toUpperCase()} ${config.url}`); - return config; - }, - (error) => Promise.reject(error) + console.log(`[Axios] ${config.method?.toUpperCase()} ${config.url}`); + return config; + }, + (error) => Promise.reject(error) ); // --- Response Interceptor --- api.interceptors.response.use( - (response: AxiosResponse) => response.data, - async (error) => { - console.error('[Axios Error]', error.message); - if (error.response?.status === 401) { - console.warn('Token expired — trigger refresh logic if needed'); + (response: AxiosResponse) => response.data, + async (error) => { + console.error('[Axios Error]', error.message); + if (error.response?.status === 401) { + console.warn('Token expired — trigger refresh logic if needed'); + } + return Promise.reject(error); } - return Promise.reject(error); - } ); export default api; diff --git a/src/electron/ipc/ipcHandler.ts b/src/electron/ipc/ipcHandler.ts index c73db15..bbccd1d 100644 --- a/src/electron/ipc/ipcHandler.ts +++ b/src/electron/ipc/ipcHandler.ts @@ -2,6 +2,7 @@ import { ipcMain } from 'electron'; import { getToken, saveToken, clearToken } from '../utils/tokenHelper.js'; import { handleLogin, takeScreenshot } from '../utils/utilityFunctions.js'; +import api from '../api/axiosClient.js'; ipcMain.handle('get-token', async (_, TOKEN_KEY: string) => { return await getToken(TOKEN_KEY); @@ -25,4 +26,11 @@ ipcMain.handle('upload-screenshot', async () => { // Handle login request from renderer ipcMain.handle('login-request', async (event, credentials: { email: string, password: string }) => { return handleLogin(credentials); +}); + +ipcMain.handle('logout-request', async () => { + (async () => { + console.log("Handle Logout listened") + await api.get("/logout"); + })() }); \ No newline at end of file diff --git a/src/electron/preload.ts b/src/electron/preload.ts index 0d1361c..0c417c0 100644 --- a/src/electron/preload.ts +++ b/src/electron/preload.ts @@ -16,7 +16,11 @@ contextBridge.exposeInMainWorld('electron', { }), getStaticData: () => ipcInvoke('getStaticData'), sendFrameAction: (payload) => ipcSend('sendFrameAction', payload), + login: (credentials: { email: string, password: string }) => ipcRenderer.invoke('login-request', credentials), + + logout: () => ipcRenderer.invoke('logout-request'), + getToken: (TOKEN_KEY: string) => ipcRenderer.invoke('get-token', TOKEN_KEY), uploadScreenshot: () => ipcRenderer.invoke('upload-screenshot'), } satisfies Window['electron']); diff --git a/src/ui/layout/DashboardLayout.tsx b/src/ui/layout/DashboardLayout.tsx index cb3ecac..0b98ec9 100644 --- a/src/ui/layout/DashboardLayout.tsx +++ b/src/ui/layout/DashboardLayout.tsx @@ -68,25 +68,25 @@ const DashboardLayout: React.FC = ({ setUser }) => { const navigate = useNavigate(); const location = useLocation(); - - // Tracking states - const [selectedProject, setSelectedProject] = useState(null); - const [isTracking, setIsTracking] = useState(false); - const [isPaused, setIsPaused] = useState(false); - const [elapsedTime, setElapsedTime] = useState(0); - const [startTime, setStartTime] = useState(null); - const [endTime, setEndTime] = useState(null); - const timerRef = useRef | null>(null); - - const [projectsData, setProjectsData] = useState([ - { id: 1, projectName: "CRM Redesign", clientName: "Salesforce" }, - { id: 2, projectName: "AI Assistant", clientName: "OpenAI" }, - { id: 3, projectName: "Marketing Dashboard", clientName: "Google" }, - ]); - - const [projectTrackingMap, setProjectTrackingMap] = useState< - Map - >(new Map()); + + // Tracking states + const [selectedProject, setSelectedProject] = useState(null); + const [isTracking, setIsTracking] = useState(false); + const [isPaused, setIsPaused] = useState(false); + const [elapsedTime, setElapsedTime] = useState(0); + const [startTime, setStartTime] = useState(null); + const [endTime, setEndTime] = useState(null); + const timerRef = useRef | null>(null); + + const [projectsData, setProjectsData] = useState([ + { id: 1, projectName: "CRM Redesign", clientName: "Salesforce" }, + { id: 2, projectName: "AI Assistant", clientName: "OpenAI" }, + { id: 3, projectName: "Marketing Dashboard", clientName: "Google" }, + ]); + + const [projectTrackingMap, setProjectTrackingMap] = useState< + Map + >(new Map()); useEffect(() => { const handleResize = () => { @@ -100,9 +100,20 @@ const DashboardLayout: React.FC = ({ setUser }) => { return () => window.removeEventListener("resize", handleResize); }, []); - const handleLogout = () => { + const handleLogout = async () => { localStorage.removeItem("user"); setUser(null); + + console.log("calling Logout UI") + + + try { + const res = await window.electron.logout() + console.log(res) + } catch (error) { + console.log(error) + } + navigate("/login"); }; @@ -122,7 +133,7 @@ const DashboardLayout: React.FC = ({ setUser }) => { ]; - // Sync global states with selected project tracking data + // Sync global states with selected project tracking data useEffect(() => { if (selectedProject) { const projectData = projectTrackingMap.get(selectedProject.id); @@ -159,7 +170,7 @@ const DashboardLayout: React.FC = ({ setUser }) => { current.isTracking = true; current.isPaused = false; updated.set(project.id, current); - + return updated; }); @@ -173,7 +184,7 @@ const DashboardLayout: React.FC = ({ setUser }) => { setProjectTrackingMap((prev) => { const updated = new Map(prev); const current = updated.get(project.id); - + // Only increment when tracking AND not paused if (current && current.isTracking && !current.isPaused) { current.elapsedTime += 1; @@ -187,25 +198,25 @@ const DashboardLayout: React.FC = ({ setUser }) => { // Pause/Resume tracking const handlePauseResume = () => { if (!selectedProject) return; - + // Get current state before toggling to avoid double-click issues const currentProjectData = projectTrackingMap.get(selectedProject.id); if (!currentProjectData || !currentProjectData.isTracking) return; - + const newPausedState = !currentProjectData.isPaused; - + setProjectTrackingMap((prev) => { const updated = new Map(prev); const current = updated.get(selectedProject.id); if (!current) return updated; - + // Set the new pause state current.isPaused = newPausedState; updated.set(selectedProject.id, { ...current }); - + return updated; }); - + // Update global isPaused state immediately setIsPaused(newPausedState); }; @@ -231,7 +242,7 @@ const DashboardLayout: React.FC = ({ setUser }) => { current.isPaused = false; current.endTime = now; updated.set(selectedProject.id, { ...current }); - + return updated; }); @@ -240,7 +251,7 @@ const DashboardLayout: React.FC = ({ setUser }) => { setIsPaused(false); setEndTime(new Date()); - console.log("projectTrackingMap",projectTrackingMap) + console.log("projectTrackingMap", projectTrackingMap) }; // Cleanup timer on unmount @@ -256,11 +267,11 @@ const DashboardLayout: React.FC = ({ setUser }) => { const handleProjectSelect = (id: number) => { // Only allow project selection when not tracking if (isTracking) return; - + const project = projectsData.find((p) => p.id === id); if (project) { setSelectedProject(project); - + // Load existing tracking data if available const projectData = projectTrackingMap.get(id); if (projectData) { @@ -302,12 +313,11 @@ const DashboardLayout: React.FC = ({ setUser }) => { className={` fixed md:relative inset-y-0 left-0 z-40 transform bg-base-100 border-r border-t border-base-300 transition-all duration-300 ease-in-out - ${ - isMobile - ? isSidebarOpen - ? "translate-x-0 w-64" - : "-translate-x-full w-64" - : isSidebarOpen + ${isMobile + ? isSidebarOpen + ? "translate-x-0 w-64" + : "-translate-x-full w-64" + : isSidebarOpen ? "w-50" : "w-20" } @@ -339,10 +349,9 @@ const DashboardLayout: React.FC = ({ setUser }) => { to={item.path} end={item.exact} className={({ isActive }) => - `flex items-center gap-3 my-1 font-medium transition-all duration-150 ${ - isActive - ? "bg-primary text-primary-content rounded-lg" - : "hover:bg-base-300 rounded-lg" + `flex items-center gap-3 my-1 font-medium transition-all duration-150 ${isActive + ? "bg-primary text-primary-content rounded-lg" + : "hover:bg-base-300 rounded-lg" }` } onClick={closeSidebarOnMobile} @@ -380,8 +389,8 @@ const DashboardLayout: React.FC = ({ setUser }) => { {location.pathname.includes("projects") ? "Projects" : location.pathname.includes("leave-adjustments") - ? "Leave & Adjustments" - : "Dashboard"} + ? "Leave & Adjustments" + : "Dashboard"} @@ -418,7 +427,7 @@ const DashboardLayout: React.FC = ({ setUser }) => { {/* Page Content */}
- +
diff --git a/types.d.ts b/types.d.ts index dbdba65..3263dd9 100644 --- a/types.d.ts +++ b/types.d.ts @@ -34,6 +34,7 @@ interface Window { ) => UnsubscribeFunction; sendFrameAction: (payload: FrameWindowAction) => void; login: (credentials: { email: string; password: string }) => Promise; + logout: () => {}; getToken: (tokenKey: string) => Promise; uploadScreenshot: () => {}; };