fixed issue if no project assign

This commit is contained in:
JaiPandey425 2025-12-18 15:32:19 +05:30
parent e3692467e3
commit b4403c2cd5
8 changed files with 77 additions and 42 deletions

View File

@ -1,12 +1,11 @@
[Interface] [Interface]
PrivateKey = EA2j6mOQB17w497cZS4B91m/xDzEcGz9lU3jKtc1wU8= PrivateKey = yHrWqSi5ZV4YV1cVVPBt2NbmTHd/mDWtZGVWGQe5I3s=
Address = 10.0.0.27/32 Address = 10.0.0.91/32
DNS = 1.1.1.1 DNS = 1.1.1.1
[Peer] [Peer]
PublicKey = jG+7H5thEiNjxY1XqI1R9oyMAMTIegLwE3tZkS1Rj2U= PublicKey = jG+7H5thEiNjxY1XqI1R9oyMAMTIegLwE3tZkS1Rj2U=
AllowedIPs = 10.0.0.0/24
Endpoint = 35.95.209.161:51820 Endpoint = 35.95.209.161:51820
AllowedIPs = 10.0.0.0/24 AllowedIPs = 10.0.0.0/24
PersistentKeepalive = 25 PersistentKeepalive = 25

View File

@ -1,5 +1,5 @@
// electron/api/axiosClient.ts // electron/api/axiosClient.ts
import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios'; import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse, InternalAxiosRequestConfig } from 'axios';
import { getToken } from '../utils/tokenHelper.js'; import { getToken } from '../utils/tokenHelper.js';
import chalk from "chalk"; import chalk from "chalk";
import { sendTokenExpired } from '../ipc/ipcHandler.js'; import { sendTokenExpired } from '../ipc/ipcHandler.js';
@ -8,40 +8,61 @@ import { getBaseURL } from './baseURL.js';
const TOKEN_KEY = 'ACCESS_TOKEN'; const TOKEN_KEY = 'ACCESS_TOKEN';
const Base_URL = await getBaseURL() // const Base_URL = await getBaseURL()
const httpsAgent = new https.Agent({ const httpsAgent = new https.Agent({
rejectUnauthorized: false rejectUnauthorized: false
}); });
console.log('Base_URL$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$' ,Base_URL) // console.log('Base_URL$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$' ,Base_URL)
const api: AxiosInstance = axios.create({ const api: AxiosInstance = axios.create({
// baseURL: 'https://portal-sf.docva.com/api/v1/va', // 🔁 your backend // baseURL: 'https://portal-sf.docva.com/api/v1/va', // 🔁 your backend
baseURL: `${Base_URL}/api/v1/va`, // baseURL: `${Base_URL}/api/v1/va`,
httpsAgent httpsAgent
// timeout: 10000, // timeout: 10000,
}); });
export function syncAxiosBaseURL() {
const baseURL = getBaseURL();
api.defaults.baseURL = `${baseURL}/api/v1/va`;
console.log('✅ Axios baseURL synced →', api.defaults.baseURL);
}
// console.log("Creating Axios Instance", axios.VERSION); // console.log("Creating Axios Instance", axios.VERSION);
// console.log("Axios .get reference:", api.get); // console.log("Axios .get reference:", api.get);
// console.log("Axios .request reference:", api.request); // console.log("Axios .request reference:", api.request);
// --- Request Interceptor --- // --- Request Interceptor ---
// api.interceptors.request.use(
// async (config: AxiosRequestConfig): Promise<any> => {
// const token = await getToken(TOKEN_KEY);
// config.headers = config.headers || {}
// if (token) {
// config.headers['token'] = token;
// config.headers['ngrok-skip-browser-warning'] = 'true';
// }
// return config;
// },
// (error) => Promise.reject(error)
// );
api.interceptors.request.use( api.interceptors.request.use(
async (config: AxiosRequestConfig): Promise<any> => { async (config: InternalAxiosRequestConfig) => {
const token = await getToken(TOKEN_KEY); const token = await getToken(TOKEN_KEY);
config.headers = config.headers || {}
if (token) { if (token) {
config.headers['token'] = token; config.headers.token = token;
config.headers['ngrok-skip-browser-warning'] = 'true'; config.headers['ngrok-skip-browser-warning'] = 'true';
} }
return config; return config;
}, }
(error) => Promise.reject(error)
); );
// --- Response Interceptor --- // --- Response Interceptor ---

View File

@ -1,7 +1,10 @@
import { syncAxiosBaseURL } from "./axiosClient.js";
// let CURRENT_BASE_URL = "https://portal-sf.docva.com/api/v1/va"; // let CURRENT_BASE_URL = "https://portal-sf.docva.com/api/v1/va";
let CURRENT_BASE_URL = "https://portal-sf.docva.com"; let CURRENT_BASE_URL = "https://portal-sf.docva.com";
export const getBaseURL = () => CURRENT_BASE_URL; export const getBaseURL = () => CURRENT_BASE_URL;
export const setBaseURL = (url: string) => { export const setBaseURL = (url: string) => {
CURRENT_BASE_URL = url; CURRENT_BASE_URL = url;
syncAxiosBaseURL();
}; };

View File

@ -132,7 +132,7 @@ const finalizeAndSendLogs = useCallback(
// } : null, // } : null,
// }); // });
let res = window.electron.trackingTabsOpeningClosing(payload); let res = await window.electron.trackingTabsOpeningClosing(payload);
console.log("Tracking response:", res); console.log("Tracking response:", res);
dispatch(clearProjectLogs({ projectId })); dispatch(clearProjectLogs({ projectId }));

View File

@ -152,6 +152,14 @@ const Dashboard: React.FC = () => {
}) })
); );
// FIX: Check if we have any projects
if (res.data.length === 0) {
// No projects available, clear selected project
dispatch(setSelectedProjectSlice(null));
// fetchProfile();
return;
}
// Check if we already have a selected project that's being tracked // Check if we already have a selected project that's being tracked
const currentlySelected = selectedProject; const currentlySelected = selectedProject;
const currentlyTracking = isTracking; const currentlyTracking = isTracking;
@ -208,9 +216,13 @@ const Dashboard: React.FC = () => {
fetchProfile(); fetchProfile();
} else { } else {
console.warn("⚠️ Unexpected response:", res); console.warn("⚠️ Unexpected response:", res);
// FIX: Also clear selected project on unexpected response
dispatch(setSelectedProjectSlice(null));
} }
} catch (err) { } catch (err) {
console.error("❌ Error fetching projects:", err); console.error("❌ Error fetching projects:", err);
// FIX: Clear selected project on error
dispatch(setSelectedProjectSlice(null));
} finally { } finally {
setIsRefreshing(false); setIsRefreshing(false);
} }
@ -218,6 +230,7 @@ const Dashboard: React.FC = () => {
useEffect(() => { useEffect(() => {
fetchProjects(); fetchProjects();
fetchProfile()
}, []); }, []);
const handleRefresh = async () => { const handleRefresh = async () => {
@ -285,6 +298,7 @@ const Dashboard: React.FC = () => {
<h1 className="text-md font-bold">Dashboard</h1> <h1 className="text-md font-bold">Dashboard</h1>
</div> </div>
{/* Tracking Section */} {/* Tracking Section */}
{/* Tracking Section */}
<div className="w-full mb-4"> <div className="w-full mb-4">
<div className="card bg-base-100 border border-base-200 shadow-sm card-sm"> <div className="card bg-base-100 border border-base-200 shadow-sm card-sm">
<div className="card-body"> <div className="card-body">
@ -305,11 +319,6 @@ const Dashboard: React.FC = () => {
<p className="text-lg font-extrabold text-success"> <p className="text-lg font-extrabold text-success">
{formatTime(displayTime)} {formatTime(displayTime)}
</p> </p>
{/* <p className={`text-lg font-extrabold ${isLimitReached ? 'text-error' : 'text-success'}`}>
{formatTime(displayTime)}
{isLimitReached && " ⚠️"}
</p> */}
<div> <div>
<span className="text-base-content/70">Project:</span>{" "} <span className="text-base-content/70">Project:</span>{" "}
<span className="font-semibold"> <span className="font-semibold">
@ -356,7 +365,9 @@ const Dashboard: React.FC = () => {
</> </>
) : ( ) : (
<p className="text-sm text-base-content/60 text-center"> <p className="text-sm text-base-content/60 text-center">
Select a project below to start tracking. {projectsData.length === 0
? "No projects available."
: "Select a project below to start tracking."}
</p> </p>
)} )}
</div> </div>
@ -371,7 +382,7 @@ const Dashboard: React.FC = () => {
{!selectedData?.isTracking && {!selectedData?.isTracking &&
<button <button
onClick={handleRefresh} onClick={handleRefresh}
disabled={isRefreshing } disabled={isRefreshing}
className="btn btn-xs btn-ghost gap-1 text-warning" className="btn btn-xs btn-ghost gap-1 text-warning"
title="Refresh projects" title="Refresh projects"
> >

View File

@ -9,6 +9,8 @@ const PaysSlips = () => {
const [error, setError] = useState<string | null>(null); const [error, setError] = useState<string | null>(null);
const [rows, setRows] = useState<any[]>([]); const [rows, setRows] = useState<any[]>([]);
useEffect(() => { useEffect(() => {
if (!projectSummary?.vaId) return; if (!projectSummary?.vaId) return;

View File

@ -64,13 +64,11 @@ const Timesheets: React.FC = () => {
const [lastRefreshed, setLastRefreshed] = useState<Date | null>(null); const [lastRefreshed, setLastRefreshed] = useState<Date | null>(null);
const [initialLoading, setInitialLoading] = useState(true); const [initialLoading, setInitialLoading] = useState(true);
const [tick, setTick] = useState(0); const [tick, setTick] = useState(0);
const { selectedProject } = const { selectedProject } = useSelector((state: any) => state.projects);
useSelector((state: any) => state.projects); const selectedProjectId = selectedProject?.projectId ?? null;
const activeProjects = projectsData.filter(p => p.status === "ACTIVE"); const activeProjects = projectsData.filter(p => p.status === "ACTIVE");
console.log("selectedProject", selectedProject.projectId)
useEffect(() => { useEffect(() => {
const interval = setInterval(() => { const interval = setInterval(() => {
@ -225,13 +223,13 @@ const Timesheets: React.FC = () => {
<td>{formatWorkTime(entry.totalWorkTime)}</td> <td>{formatWorkTime(entry.totalWorkTime)}</td>
<td> <td>
<button <button
disabled={(formatWorkTime(entry.totalWorkTime) === "0h 0m" || (isTracking && entry.projectId === selectedProject.projectId))} disabled={(formatWorkTime(entry.totalWorkTime) === "0h 0m" || (isTracking && entry.projectId === selectedProjectId))}
onClick={() => onClick={() =>
handleViewLogs(entry.projectId, entry.projectName) handleViewLogs(entry.projectId, entry.projectName)
} }
className="btn btn-ghost btn-xs" className="btn btn-ghost btn-xs"
> >
{(formatWorkTime(entry.totalWorkTime) === "0h 0m" || (isTracking && entry.projectId === selectedProject.projectId)) ? ( {(formatWorkTime(entry.totalWorkTime) === "0h 0m" || (isTracking && entry.projectId === selectedProjectId)) ? (
<EyeOff size={16} /> <EyeOff size={16} />
) : ( ) : (
<Eye size={16} /> <Eye size={16} />

View File

@ -7,7 +7,7 @@ interface Props {
const VpnGuard: React.FC<Props> = ({ children }) => { const VpnGuard: React.FC<Props> = ({ children }) => {
const VPN_API = "http://10.0.0.1:3000"; const VPN_API = "http://10.0.0.1";
const DEFAULT_API = "https://portal-sf.docva.com" const DEFAULT_API = "https://portal-sf.docva.com"
const [checking, setChecking] = useState(true); const [checking, setChecking] = useState(true);
@ -66,6 +66,7 @@ const VpnGuard: React.FC<Props> = ({ children }) => {
console.log("vpnRes", vpnRes); console.log("vpnRes", vpnRes);
if (vpnRes) { if (vpnRes) {
// Run VPN check again AFTER URL changes // Run VPN check again AFTER URL changes
await checkVPN(); await checkVPN();
} else { } else {