diff --git a/src/electron/ipc/ipcHandler.ts b/src/electron/ipc/ipcHandler.ts index 59349ca..6e76996 100644 --- a/src/electron/ipc/ipcHandler.ts +++ b/src/electron/ipc/ipcHandler.ts @@ -58,15 +58,15 @@ export const registerIPCHandlers = (mainWindow: BrowserWindow) => { -ipcMain.handle("resize-window", (event, width: number, height: number) => { - const mainWindow = getMainWindow(); - if (mainWindow && !mainWindow.isDestroyed()) { - console.log(`📏 Resizing window to ${width}x${height}`); - mainWindow.setResizable(true); // temporarily enable resizing - mainWindow.setSize(width, height); - mainWindow.setResizable(false); // disable again if you want to lock it - } -}); + ipcMain.handle("resize-window", (event, width: number, height: number) => { + const mainWindow = getMainWindow(); + if (mainWindow && !mainWindow.isDestroyed()) { + console.log(`📏 Resizing window to ${width}x${height}`); + mainWindow.setResizable(true); // temporarily enable resizing + mainWindow.setSize(width, height); + mainWindow.setResizable(false); // disable again if you want to lock it + } + }); // ✅ Start background polling when main window is ready @@ -86,9 +86,9 @@ ipcMain.handle("get-project-list", async () => { return JSON.parse(JSON.stringify(res)); } catch (error: any) { console.error(" get-project-list error:", error); - return { - success: false, - message: error?.message || String(error) || "Unknown error" + return { + success: false, + message: error?.message || String(error) || "Unknown error" }; } }); @@ -165,7 +165,7 @@ ipcMain.handle("tracking-tabs-opening-and-closing", async (event, payload) => { // console.log("get-project-logs",projectID) // const response = await api.get(`/report/project/${projectID}`); // console.log("response-logs 164" , response) - + // return response; // } catch (error) { // console.error("Error fetching project logs:", error); @@ -180,7 +180,7 @@ ipcMain.handle("get-project-logs", async (event, { projectID, fromDate, toDate } let url = `/report/project/${projectID}`; - + // 🧠 Append query params only if dates are provided if (fromDate && toDate) { @@ -191,7 +191,7 @@ ipcMain.handle("get-project-logs", async (event, { projectID, fromDate, toDate } url += `?${params.toString()}`; } - console.log("url" , url) + console.log("url", url) const response = await api.get(url); console.log("✅ response-logs:", response); @@ -206,7 +206,7 @@ ipcMain.handle("get-project-logs", async (event, { projectID, fromDate, toDate } ipcMain.handle("forgot-password", async (event, email: string) => { try { const response = await api.post("/forgot-password", { email }); - console.log(response , "Line response") + console.log(response, "Line response") if (response) { return { success: true, message: response.data?.message }; } @@ -218,3 +218,49 @@ ipcMain.handle("forgot-password", async (event, email: string) => { }; } }); + + +ipcMain.handle("get-profile", async () => { + try { + const response = await api.get("/profile"); + console.log(response.data) + return { + success: true, + data: response.data, + }; + } catch (error: any) { + console.error(" Profile fetch error:", error.response?.data || error.message); + return { + success: false, + message: error.response?.data?.message || "Something went wrong", + }; + } +}); + + +ipcMain.handle("change-password", async (event, data) => { + console.log("data-change-password", data) + + + // Build final payload + const payload = { + userDetails: { + oldPassword: data.oldPassword, + password: data.password, + cPassword: data.cPassword, + }, + }; + + console.log("Change Password payload" , payload) + try { + const response = await api.patch("/profile", payload); + console.log("Chnage-passowrd-response", response) + return { success: true, data: response.data }; + } catch (error: any) { + console.error("❌ Change password error:", error.message); + return { + success: false, + message: error.response?.data?.message || "Password update failed", + }; + } +}); diff --git a/src/electron/preload.cts b/src/electron/preload.cts index 3c4fac2..c885819 100644 --- a/src/electron/preload.cts +++ b/src/electron/preload.cts @@ -26,6 +26,11 @@ contextBridge.exposeInMainWorld('electron', { toDate?: string ) => ipcRenderer.invoke("get-project-logs", { projectID, fromDate, toDate }), +getProfile: () => ipcRenderer.invoke("get-profile"), + +changePassword: (data: { oldPassword: string; password: string; cPassword: string }) => + ipcRenderer.invoke("change-password", data), + } satisfies Window['electron']); // function ipcInvoke( diff --git a/src/ui/layout/DashboardLayout.tsx b/src/ui/layout/DashboardLayout.tsx index 6a8b46c..e748606 100644 --- a/src/ui/layout/DashboardLayout.tsx +++ b/src/ui/layout/DashboardLayout.tsx @@ -29,6 +29,7 @@ import { useDispatch, useSelector } from "react-redux"; import { RootState } from "../store"; import { setProjectsDataSlice, setProjectSummarySlice, setSelectedProjectSlice } from "../store/projectSlice"; import { clearUser } from "../store/userSlice"; +import { setError, setLoading, setProfile } from "../store/profileSlice"; // interface User { // email: string; @@ -116,15 +117,32 @@ const DashboardLayout = () => { }); const [activeProjectLogId, setActiveProjectLogId] = useState("") - const { finalizeTracking } = useActiveAppTracker( + const { finalizeTracking } = useActiveAppTracker( isTracking, activeProjectLogId, selectedProject?.projectId ?? null, - selectedProject?.projectName ?? null + selectedProject?.projectName ?? null ); const [projectsData, setProjectsData] = useState([]); + const fetchProfile = async () => { + try { + dispatch(setLoading(true)); + const res = await window.electron.getProfile(); + console.log("Profile", res) + if (res.success && res.data) { + dispatch(setProfile(res.data)); + } else { + dispatch(setError("Failed to fetch profile")); + } + } catch (err: any) { + dispatch(setError(err.message)); + } finally { + dispatch(setLoading(false)); + } + }; + // fetch the project list of VA useEffect(() => { const fetchProjects = async () => { @@ -177,7 +195,7 @@ const DashboardLayout = () => { const updated = new Map(prev); if (!updated.has(firstProject.projectId)) { updated.set(firstProject.projectId, { - elapsedTime:initialElapsedTime, + elapsedTime: initialElapsedTime, startTime: null, endTime: null, isTracking: false, @@ -192,6 +210,8 @@ const DashboardLayout = () => { // Set the initial elapsed time in the component state setElapsedTime(initialElapsedTime); } + fetchProfile() + } else { console.warn("⚠️ Unexpected response:", res); } @@ -209,14 +229,14 @@ const DashboardLayout = () => { const handleLogout = async () => { try { - const res = await window.electron.logout(); - if (res) { - dispatch(clearUser()); // ✅ Removes from Redux + localStorage - navigate("/login"); + const res = await window.electron.logout(); + if (res) { + dispatch(clearUser()); // ✅ Removes from Redux + localStorage + navigate("/login"); + } + } catch (error) { + console.error("Logout error:", error); } - } catch (error) { - console.error("Logout error:", error); - } }; @@ -441,51 +461,51 @@ const DashboardLayout = () => { // Handle project selection const handleProjectSelect = (projectId: string) => { - if (isTracking) return; // prevent switching while tracking + if (isTracking) return; // prevent switching while tracking - const project = projectsData.find((p) => p.projectId === projectId); - if (!project) return; + const project = projectsData.find((p) => p.projectId === projectId); + if (!project) return; - setSelectedProject(project); - dispatch(setSelectedProjectSlice(project)); + setSelectedProject(project); + dispatch(setSelectedProjectSlice(project)); - const existingData = projectTrackingMap.get(projectId); + const existingData = projectTrackingMap.get(projectId); - setProjectTrackingMap((prev) => { - const updated = new Map(prev); + setProjectTrackingMap((prev) => { + const updated = new Map(prev); - // If project is not yet tracked, initialize it with totalWorkMs - if (!existingData) { - const initialElapsedTime = Math.floor((project.totalWorkMs || 0) / 1000); - updated.set(projectId, { - elapsedTime: initialElapsedTime, - startTime: null, - endTime: null, - isTracking: false, - isPaused: false, - pauseStartTime: null, - totalPausedTime: 0, - accumulatedTime: initialElapsedTime, - }); + // If project is not yet tracked, initialize it with totalWorkMs + if (!existingData) { + const initialElapsedTime = Math.floor((project.totalWorkMs || 0) / 1000); + updated.set(projectId, { + elapsedTime: initialElapsedTime, + startTime: null, + endTime: null, + isTracking: false, + isPaused: false, + pauseStartTime: null, + totalPausedTime: 0, + accumulatedTime: initialElapsedTime, + }); - // Update component-level state - setElapsedTime(initialElapsedTime); - setStartTime(null); - setEndTime(null); - setIsTracking(false); - setIsPaused(false); - } else { - // If already tracked, restore its state - setElapsedTime(existingData.elapsedTime); - setStartTime(existingData.startTime); - setEndTime(existingData.endTime); - setIsTracking(existingData.isTracking); - setIsPaused(existingData.isPaused); - } + // Update component-level state + setElapsedTime(initialElapsedTime); + setStartTime(null); + setEndTime(null); + setIsTracking(false); + setIsPaused(false); + } else { + // If already tracked, restore its state + setElapsedTime(existingData.elapsedTime); + setStartTime(existingData.startTime); + setEndTime(existingData.endTime); + setIsTracking(existingData.isTracking); + setIsPaused(existingData.isPaused); + } - return updated; - }); -}; + return updated; + }); + }; const trackingState: TrackingState = { @@ -593,7 +613,7 @@ const DashboardLayout = () => {
{/* Sidebar */}