sec remove show min

This commit is contained in:
JaiPandey425 2025-11-14 16:49:48 +05:30
parent 44d790abab
commit d6481a0c27
7 changed files with 94 additions and 45 deletions

View File

@ -274,6 +274,27 @@ ipcMain.handle("change-password", async (event, data) => {
}); });
ipcMain.handle("get-project-summary", async (_, { projectId, date }) => {
try {
const url = `/timesheet/summary/${projectId}/${date}`;
console.log("📡 Fetching summary:", url);
const res = await api.get(url);
return {
success: true,
data: res.data,
};
} catch (error: any) {
console.error("❌ Error fetching summary:", error.message);
return {
success: false,
message: error.response?.data?.message || "Something went wrong",
};
}
});
export const sendTokenExpired = () => { export const sendTokenExpired = () => {
console.log("⚠️ Sending token-expired event to renderer"); console.log("⚠️ Sending token-expired event to renderer");

View File

@ -43,6 +43,10 @@ contextBridge.exposeInMainWorld('electron', {
}); });
}, },
getProjectSummary: (projectId: string, date: string) =>
ipcRenderer.invoke("get-project-summary", { projectId, date }),
} satisfies Window['electron']); } satisfies Window['electron']);
// function ipcInvoke<Key extends keyof EventPayloadMapping>( // function ipcInvoke<Key extends keyof EventPayloadMapping>(

View File

@ -548,7 +548,7 @@ const DashboardLayout = () => {
const hrs = Math.floor(seconds / 3600); const hrs = Math.floor(seconds / 3600);
const mins = Math.floor((seconds % 3600) / 60); const mins = Math.floor((seconds % 3600) / 60);
const secs = seconds % 60; const secs = seconds % 60;
return `${hrs}h ${mins}m ${secs}s`; return `${hrs}h ${mins}m`;
}; };
const toggleWindowSize = useRef(true); const toggleWindowSize = useRef(true);
@ -651,13 +651,14 @@ const DashboardLayout = () => {
</NavLink> </NavLink>
</div> </div>
))} ))}
<button
{!isTracking && <button
onClick={handleLogout} onClick={handleLogout}
className="flex items-center justify-center w-10 h-10 rounded-lg transition-all duration-150 hover:bg-error/10 text-error hover:text-error mt-auto cursor-pointer tooltip tooltip-right " className="flex items-center justify-center w-10 h-10 rounded-lg transition-all duration-150 hover:bg-error/10 text-error hover:text-error mt-auto cursor-pointer tooltip tooltip-right "
data-tip={"Logout"} data-tip={"Logout"}
> >
<LogOut size={18} /> <LogOut size={18} />
</button> </button>}
</aside> </aside>
{/* Main Content */} {/* Main Content */}

View File

@ -41,7 +41,8 @@ const formatTime = (seconds: number) => {
const hrs = Math.floor(seconds / 3600); const hrs = Math.floor(seconds / 3600);
const mins = Math.floor((seconds % 3600) / 60); const mins = Math.floor((seconds % 3600) / 60);
const secs = seconds % 60; const secs = seconds % 60;
return `${hrs}h ${mins}m ${secs}s`; // return `${hrs}h ${mins}m ${secs}s`;
return `${hrs}h ${mins}m `;
}; };
// Widget Component // Widget Component
@ -95,6 +96,17 @@ const Dashboard: React.FC = () => {
? projectTrackingMap.get(selectedProject.projectId) ? projectTrackingMap.get(selectedProject.projectId)
: null; : null;
const formatWorkTime = (time: string) => {
if (!time) return "0h 0m";
// Example input: "0h 2m 29s"
const parts = time.split(" ");
// Always return first two parts: ["0h", "2m"]
return parts.slice(0, 2).join(" ");
};
return ( return (
<main className="flex-1 overflow-hidden no-scrollbar max-h-screen"> <main className="flex-1 overflow-hidden no-scrollbar max-h-screen">
{/* Header */} {/* Header */}
@ -263,7 +275,7 @@ const Dashboard: React.FC = () => {
<td className="text-xs opacity-70">{index + 1}</td> <td className="text-xs opacity-70">{index + 1}</td>
<td className="font-medium">{project.projectName}</td> <td className="font-medium">{project.projectName}</td>
<td className="font-mono text-xs"> <td className="font-mono text-xs">
{project.totalWorkTime || "0h 0m 0s"} {formatWorkTime(project.totalWorkTime)}
</td> </td>
<td> <td>
<button <button
@ -283,7 +295,7 @@ const Dashboard: React.FC = () => {
</div> </div>
) : ( ) : (
<div className="flex items-center justify-center flex-1 text-sm text-base-content/60"> <div className="flex items-center justify-center flex-1 text-sm text-base-content/60">
<NoData/> <NoData />
</div> </div>
)} )}
</div> </div>

View File

@ -172,35 +172,33 @@ const LeaveAndAdjustments: React.FC = () => {
// const fetchLogs = async () => { const fetchLogs = async () => {
// const res = await window.electron.getProjectLogs( try {
// selectedProjectId, console.log("Sending =>", selectedProjectId, selectedDate);
// selectedDate || undefined,
// selectedDate || undefined, const res = await window.electron.getProjectSummary(
// ); selectedProjectId,
selectedDate
);
console.log("📥 Summary Response:", res);
// if (res.success) { // if (res.success) {
// console.log("✅ Logs: fetchLogs", res); // // setProjectLogs(res.data); // <-- store logs in state
// // Safely extract time if from/to exist
// const fromTime = res.from ? new Date(res.from).toISOString().slice(11, 16) : "";
// const toTime = res.to ? new Date(res.to).toISOString().slice(11, 16) : "";
// setPtoLeave({
// fromDate: fromTime,
// toDate: toTime,
// });
// } else { // } else {
// console.warn("⚠️ Failed to fetch project logs"); // console.warn("⚠️ Summary API failed:", res.message);
// } // }
// }; } catch (err) {
console.error("❌ Error fetching project summary:", err);
}
};
// useEffect(() => { useEffect(() => {
// if (selectedProjectId && selectedDate) { if (selectedProjectId && selectedDate) {
// fetchLogs() fetchLogs()
// } }
// }, [selectedProjectId, selectedDate]) }, [selectedProjectId, selectedDate])
return ( return (

View File

@ -92,6 +92,16 @@ const Timesheets: React.FC = () => {
} }
}; };
const formatWorkTime = (time: string) => {
if (!time) return "0h 0m";
// Example input: "0h 2m 29s"
const parts = time.split(" ");
// Always return first two parts: ["0h", "2m"]
return parts.slice(0, 2).join(" ");
};
return ( return (
@ -154,7 +164,7 @@ const Timesheets: React.FC = () => {
<tr key={entry.projectId}> <tr key={entry.projectId}>
<td>{index+1}</td> <td>{index+1}</td>
<td>{entry.projectName}</td> <td>{entry.projectName}</td>
<td>{entry.totalWorkTime}</td> <td>{formatWorkTime(entry.totalWorkTime)}</td>
<td> <td>
<button <button
onClick={() => handleViewLogs(entry.projectId, entry.projectName)} onClick={() => handleViewLogs(entry.projectId, entry.projectName)}

23
types.d.ts vendored
View File

@ -33,7 +33,7 @@ interface ProjectListResponse {
totalWorkTime?: string; totalWorkTime?: string;
totalWorkMs?: number; totalWorkMs?: number;
data?: any[]; // you can replace `any[]` with a typed array later data?: any[]; // you can replace `any[]` with a typed array later
status : number status: number
} }
interface TabActivity { interface TabActivity {
@ -75,14 +75,14 @@ interface ProfileData {
accountHolderName: string; accountHolderName: string;
accountNumber: string; accountNumber: string;
routingNumber: string; routingNumber: string;
phone:string; phone: string;
skype:string; skype: string;
city:string; city: string;
state:string; state: string;
country:string; country: string;
paymentMethod:string; paymentMethod: string;
payoneerAccount:string; payoneerAccount: string;
veemAccount:string; veemAccount: string;
_id: string; _id: string;
} }
@ -143,7 +143,10 @@ interface Window {
}) => Promise<{ success: boolean; message?: string; data?: any }>; }) => Promise<{ success: boolean; message?: string; data?: any }>;
onTokenExpired: (callback: () => void) => void; onTokenExpired: (callback: () => void) => void;
getProjectSummary: (projectId: string, date: string) => Promise<any>;
}; };
} }