- {isStopping ? (
- // Skeleton for left side during stop
-
- ) : selectedProject ? (
- isTracking ? (
-
+
+ {/* Header */}
+ {isTracking &&
+
+
+ {isStopping ? (
+ // Skeleton for left side during stop
+
+ ) : selectedProject ? (
+ isTracking ? (
+
+ ) : (
+
+ )
) : (
- )
- ) : (
+ )}
+
+ {!isStopping && selectedProject ? (
+
+ {selectedProject.projectName}
+
+ ) : !isStopping ? (
+
+ No Project Selected
+
+ ) : null}
+
+
+
+ {isStopping ? (
+ // Skeleton for right side during stop
+
+ ) : (
+ <>
+
+ {formatTime(
+ isTracking ? elapsedTime : parseTimeStringToSeconds(selectedProject?.totalWorkTime || "0h 0m 0s")
+ )}
+
+
+ {/*
+
+ */}
+
+
+ >
+ )}
+
+
+ }
+
+ {/* Layout Body */}
+
+ {/* Sidebar */}
+
- {!isStopping && selectedProject ? (
-
- {selectedProject.projectName}
-
- ) : !isStopping ? (
-
- No Project Selected
-
- ) : null}
-
+ {/* Main Content */}
+
+
+
-
- {isStopping ? (
- // Skeleton for right side during stop
-
- ) : (
- <>
-
- {formatTime(
- isTracking ? elapsedTime : parseTimeStringToSeconds(selectedProject?.totalWorkTime || "0h 0m 0s")
- )}
-
-
-
-
-
-
-
- >
- )}
-
-
- }
-
- {/* Layout Body */}
-
- {/* Sidebar */}
-
-
- {/* Main Content */}
-
-
-
-
-
setShowLogoutModal(false)}
- onConfirm={handleLogout}
- />
+ setShowLogoutModal(false)}
+ onConfirm={handleLogout}
+ />
+
-
>
);
};
diff --git a/src/ui/pages/Dashboard.tsx b/src/ui/pages/Dashboard.tsx
index 26d8220..fd6f7e9 100644
--- a/src/ui/pages/Dashboard.tsx
+++ b/src/ui/pages/Dashboard.tsx
@@ -1,5 +1,5 @@
import React, { useEffect, useRef, useState } from "react";
-import { Clock, TrendingUp, Play, Square, ProjectorIcon, Pause } from "lucide-react";
+import { Clock, TrendingUp, Play, Square, ProjectorIcon, Pause, RefreshCw } from "lucide-react";
import { useOutletContext } from "react-router-dom";
import NoData from "./NoData";
import { useDispatch, useSelector } from "react-redux";
@@ -105,6 +105,7 @@ const Dashboard: React.FC = () => {
const selectedProject = useSelector((state: any) => state.projects.selectedProject);
const projectSummary = useSelector((state: any) => state.projects.projectSummary);
const projectTrackingMap = useSelector((state: any) => state.projects.projectTrackingMap);
+ const [isRefreshing, setIsRefreshing] = useState(false);
console.log("Line 111", projectsData, selectedProject, projectTrackingMap)
@@ -127,60 +128,66 @@ const Dashboard: React.FC = () => {
}
};
- useEffect(() => {
- const fetchProjects = async () => {
- try {
- console.log("📡 Fetching projects...Dashboard");
- const res = await window.electron.getProjectList();
- console.log(" Project list response in dashboard:", res);
+ const fetchProjects = async () => {
+ try {
+ console.log("📡 Fetching projects...Dashboard");
+ const res = await window.electron.getProjectList();
+ console.log(" Project list response in dashboard:", res);
- if (res?.success && Array.isArray(res.data)) {
- // Store data redux store
- dispatch(setProjectsDataSlice(res.data));
+ if (res?.success && Array.isArray(res.data)) {
+ // Store data redux store
+ dispatch(setProjectsDataSlice(res.data));
+ dispatch(
+ setProjectSummarySlice({
+ totalProjects: res.totalProjects || 0,
+ activeProjects: res.activeProjects || 0,
+ awayProjects: res.awayProjects || 0,
+ totalWorkTime: res.totalWorkTime || "0h 0m 0s",
+ totalWorkMs: res.totalWorkMs || 0,
+ vaName: res.vaName || "",
+ vaId: res.vaId || "",
+ })
+ );
+
+ // Auto-select first project
+ if (res.data.length > 0 && !selectedProject) {
+ const firstProject = res.data[0];
+
+ // Select the project
+ dispatch(setSelectedProjectSlice(firstProject));
+
+ const initialElapsed = parseTimeStringToSeconds(firstProject.totalWorkTime);
+
+ // Initialize tracking data for first project
dispatch(
- setProjectSummarySlice({
- totalProjects: res.totalProjects || 0,
- activeProjects: res.activeProjects || 0,
- awayProjects: res.awayProjects || 0,
- totalWorkTime: res.totalWorkTime || "0h 0m 0s",
- totalWorkMs: res.totalWorkMs || 0,
- vaName: res.vaName || "",
- vaId: res.vaId || "",
+ initializeProjectTracking({
+ projectId: firstProject.projectId,
+ initialTime: initialElapsed,
})
);
-
- // Auto-select first project
- if (res.data.length > 0 && !selectedProject) {
- const firstProject = res.data[0];
-
- // Select the project
- dispatch(setSelectedProjectSlice(firstProject));
-
- const initialElapsed = parseTimeStringToSeconds(firstProject.totalWorkTime);
-
- // Initialize tracking data for first project
- dispatch(
- initializeProjectTracking({
- projectId: firstProject.projectId,
- initialTime: initialElapsed,
- })
- );
- }
-
- fetchProfile()
-
- } else {
- console.warn("⚠️ Unexpected response:", res);
}
- } catch (err) {
- console.error("❌ Error fetching projects:", err);
- }
- };
+ fetchProfile()
+
+ } else {
+ console.warn("⚠️ Unexpected response:", res);
+ }
+ } catch (err) {
+ console.error("❌ Error fetching projects:", err);
+ }
+ };
+
+ useEffect(() => {
fetchProjects();
}, []);
+ const handleRefresh = async () => {
+ setIsRefreshing(true);
+ await fetchProjects();
+ setTimeout(() => setIsRefreshing(false), 500); // Small delay for visual feedback
+ };
+
const selectedData = selectedProject
? projectTrackingMap[selectedProject.projectId]
: null;
@@ -234,7 +241,7 @@ const Dashboard: React.FC = () => {
};
return (
-
+
{/* Header */}
Dashboard
@@ -243,7 +250,7 @@ const Dashboard: React.FC = () => {
- {isStopping ? (
+ {(isStopping || isRefreshing) ? (
// Skeleton loader for tracking section
@@ -318,10 +325,19 @@ const Dashboard: React.FC = () => {
{/* 🔹 Sticky Header */}
{/* 🔹 Table or Empty State or Skeleton */}
- {isStopping ? (
+ {(isStopping || isRefreshing) ? (
// Skeleton loader for projects table
{[...Array(3)].map((_, index) => (
diff --git a/src/ui/pages/Timesheets/Timesheets.tsx b/src/ui/pages/Timesheets/Timesheets.tsx
index 51bc4b0..943104d 100644
--- a/src/ui/pages/Timesheets/Timesheets.tsx
+++ b/src/ui/pages/Timesheets/Timesheets.tsx
@@ -106,7 +106,7 @@ const Timesheets: React.FC = () => {
return (
-
+
{/* Header */}
@@ -150,7 +150,7 @@ const Timesheets: React.FC = () => {
*/}
{/* Timesheet Table */}
-