diff --git a/banner.js b/banner.js new file mode 100644 index 0000000..a9c791d --- /dev/null +++ b/banner.js @@ -0,0 +1,8 @@ +import figlet from "figlet"; +import chalk from "chalk"; + +figlet("Jai Pandey DocVA", (err, data) => { + if (err) return console.log("Error generating banner"); + console.log(chalk.cyan(data)); + console.log(chalk.green("\nπŸš€ Development Mode Starting...\n")); +}); diff --git a/package-lock.json b/package-lock.json index 814a5f6..f4893ed 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ "axios": "^1.13.2", "chalk": "^5.6.2", "electron-store": "^11.0.2", + "figlet": "^1.9.4", "https": "^1.0.0", "lucide-react": "^0.552.0", "luxon": "^3.7.2", @@ -84,7 +85,6 @@ "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", @@ -770,9 +770,9 @@ } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", - "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", "cpu": [ "ppc64" ], @@ -782,13 +782,13 @@ "aix" ], "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/@esbuild/android-arm": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", - "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", "cpu": [ "arm" ], @@ -798,13 +798,13 @@ "android" ], "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/@esbuild/android-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", - "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", "cpu": [ "arm64" ], @@ -814,13 +814,13 @@ "android" ], "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/@esbuild/android-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", - "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", "cpu": [ "x64" ], @@ -830,13 +830,13 @@ "android" ], "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", - "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", "cpu": [ "arm64" ], @@ -846,13 +846,13 @@ "darwin" ], "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", - "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", "cpu": [ "x64" ], @@ -862,13 +862,13 @@ "darwin" ], "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", - "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", "cpu": [ "arm64" ], @@ -878,13 +878,13 @@ "freebsd" ], "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", - "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", "cpu": [ "x64" ], @@ -894,13 +894,13 @@ "freebsd" ], "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/@esbuild/linux-arm": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", - "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", "cpu": [ "arm" ], @@ -910,13 +910,13 @@ "linux" ], "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", - "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", "cpu": [ "arm64" ], @@ -926,13 +926,13 @@ "linux" ], "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", - "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", "cpu": [ "ia32" ], @@ -942,13 +942,13 @@ "linux" ], "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", - "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", "cpu": [ "loong64" ], @@ -958,13 +958,13 @@ "linux" ], "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", - "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", "cpu": [ "mips64el" ], @@ -974,13 +974,13 @@ "linux" ], "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", - "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", "cpu": [ "ppc64" ], @@ -990,13 +990,13 @@ "linux" ], "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", - "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", "cpu": [ "riscv64" ], @@ -1006,13 +1006,13 @@ "linux" ], "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", - "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", "cpu": [ "s390x" ], @@ -1022,13 +1022,13 @@ "linux" ], "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/@esbuild/linux-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", - "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", "cpu": [ "x64" ], @@ -1038,29 +1038,13 @@ "linux" ], "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", - "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", - "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", "cpu": [ "x64" ], @@ -1070,29 +1054,13 @@ "netbsd" ], "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", - "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", - "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", "cpu": [ "x64" ], @@ -1102,29 +1070,13 @@ "openbsd" ], "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openharmony-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", - "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", - "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", "cpu": [ "x64" ], @@ -1134,13 +1086,13 @@ "sunos" ], "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", - "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", "cpu": [ "arm64" ], @@ -1150,13 +1102,13 @@ "win32" ], "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", - "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", "cpu": [ "ia32" ], @@ -1166,7 +1118,7 @@ "win32" ], "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/@esbuild/win32-x64": { @@ -2944,7 +2896,6 @@ "integrity": "sha512-RFA/bURkcKzx/X9oumPG9Vp3D3JUgus/d0b67KB0t5S/raciymilkOa66olh78MUI92QLbEJevO7rvqU/kjwKA==", "devOptional": true, "license": "MIT", - "peer": true, "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" @@ -3213,7 +3164,6 @@ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -3416,6 +3366,7 @@ "integrity": "sha512-+25nxyyznAXF7Nef3y0EbBeqmGZgeN/BxHX29Rs39djAfaFalmQ89SE6CWyDCHzGL0yt/ycBtNOmGTW0FyGWNw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "archiver-utils": "^2.1.0", "async": "^3.2.4", @@ -3435,6 +3386,7 @@ "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "glob": "^7.1.4", "graceful-fs": "^4.2.0", @@ -3456,7 +3408,8 @@ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/archiver-utils/node_modules/readable-stream": { "version": "2.3.8", @@ -3464,6 +3417,7 @@ "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -3479,7 +3433,8 @@ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/archiver-utils/node_modules/string_decoder": { "version": "1.1.1", @@ -3487,6 +3442,7 @@ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "safe-buffer": "~5.1.0" } @@ -3771,7 +3727,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "baseline-browser-mapping": "^2.8.25", "caniuse-lite": "^1.0.30001754", @@ -4362,6 +4317,7 @@ "integrity": "sha512-D3uMHtGc/fcO1Gt1/L7i1e33VOvD4A9hfQLP+6ewd+BvG/gQ84Yh4oftEhAdjSMgBgwGL+jsppT7JYNpo6MHHg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "buffer-crc32": "^0.2.13", "crc32-stream": "^4.0.2", @@ -4563,6 +4519,7 @@ "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", "dev": true, "license": "Apache-2.0", + "peer": true, "bin": { "crc32": "bin/crc32.njs" }, @@ -4576,6 +4533,7 @@ "integrity": "sha512-NT7w2JVU7DFroFdYkeq8cywxrgjPHWkdX1wjpRQXPX5Asews3tA+Ght6lddQO5Mkumffp3X7GEqku3epj2toIw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "crc-32": "^1.2.0", "readable-stream": "^3.4.0" @@ -5047,7 +5005,6 @@ "integrity": "sha512-NoXo6Liy2heSklTI5OIZbCgXC1RzrDQsZkeEwXhdOro3FT1VBOvbubvscdPnjVuQ4AMwwv61oaH96AbiYg9EnQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "app-builder-lib": "25.1.8", "builder-util": "25.1.7", @@ -5267,6 +5224,7 @@ "integrity": "sha512-2ntkJ+9+0GFP6nAISiMabKt6eqBB0kX1QqHNWFWAXgi0VULKGisM46luRFpIBiU3u/TDmhZMM8tzvo2Abn3ayg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "app-builder-lib": "25.1.8", "archiver": "^5.3.1", @@ -5280,6 +5238,7 @@ "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -5295,6 +5254,7 @@ "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "universalify": "^2.0.0" }, @@ -5308,6 +5268,7 @@ "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">= 10.0.0" } @@ -6104,23 +6065,6 @@ "pend": "~1.2.0" } }, - "node_modules/fdir": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", - "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", - "license": "MIT", - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } - }, "node_modules/ffi-napi": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/ffi-napi/-/ffi-napi-4.0.3.tgz", @@ -6140,6 +6084,30 @@ "node": ">=10" } }, + "node_modules/figlet": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/figlet/-/figlet-1.9.4.tgz", + "integrity": "sha512-uN6QE+TrzTAHC1IWTyrc4FfGo2KH/82J8Jl1tyKB7+z5DBit/m3D++Iu5lg91qJMnQQ3vpJrj5gxcK/pk4R9tQ==", + "license": "MIT", + "dependencies": { + "commander": "^14.0.0" + }, + "bin": { + "figlet": "bin/index.js" + }, + "engines": { + "node": ">= 17.0.0" + } + }, + "node_modules/figlet/node_modules/commander": { + "version": "14.0.2", + "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.2.tgz", + "integrity": "sha512-TywoWNNRbhoD0BXs1P3ZEScW8W5iKrnbithIl0YH+uCmBd0QpPOA8yc82DS3BIE5Ma6FnBVUsJ7wVUDz4dvOWQ==", + "license": "MIT", + "engines": { + "node": ">=20" + } + }, "node_modules/filelist": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", @@ -6260,7 +6228,8 @@ "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/fs-extra": { "version": "8.1.0", @@ -7196,7 +7165,7 @@ "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" @@ -7947,6 +7916,7 @@ "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "readable-stream": "^2.0.5" }, @@ -7959,7 +7929,8 @@ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/lazystream/node_modules/readable-stream": { "version": "2.3.8", @@ -7967,6 +7938,7 @@ "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -7982,7 +7954,8 @@ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/lazystream/node_modules/string_decoder": { "version": "1.1.1", @@ -7990,6 +7963,7 @@ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "safe-buffer": "~5.1.0" } @@ -8282,21 +8256,24 @@ "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/lodash.difference": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", "integrity": "sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/lodash.flatten": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", "integrity": "sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/lodash.isequal": { "version": "4.5.0", @@ -8310,14 +8287,16 @@ "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/lodash.union": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", "integrity": "sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/log-symbols": { "version": "4.1.0", @@ -9115,6 +9094,7 @@ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -9814,7 +9794,8 @@ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/progress": { "version": "2.0.3", @@ -9958,7 +9939,6 @@ "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", "license": "MIT", - "peer": true, "dependencies": { "loose-envify": "^1.1.0" }, @@ -9971,7 +9951,6 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", "license": "MIT", - "peer": true, "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.2" @@ -10006,7 +9985,6 @@ "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.2.0.tgz", "integrity": "sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g==", "license": "MIT", - "peer": true, "dependencies": { "@types/use-sync-external-store": "^0.0.6", "use-sync-external-store": "^1.4.0" @@ -10153,6 +10131,7 @@ "integrity": "sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==", "dev": true, "license": "Apache-2.0", + "peer": true, "dependencies": { "minimatch": "^5.1.0" } @@ -10163,6 +10142,7 @@ "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "balanced-match": "^1.0.0" } @@ -10173,6 +10153,7 @@ "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, "license": "ISC", + "peer": true, "dependencies": { "brace-expansion": "^2.0.1" }, @@ -10216,8 +10197,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz", "integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/redux-thunk": { "version": "3.1.0", @@ -11496,6 +11476,7 @@ "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "bl": "^4.0.3", "end-of-stream": "^1.4.1", @@ -11965,7 +11946,6 @@ "resolved": "https://registry.npmjs.org/vite/-/vite-7.2.6.tgz", "integrity": "sha512-tI2l/nFHC5rLh7+5+o7QjKjSR04ivXDF4jcgV0f/bTQ+OJiITy5S6gaynVsEM+7RqzufMnVbIon6Sr5x1SDYaQ==", "license": "MIT", - "peer": true, "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", @@ -12035,6 +12015,23 @@ } } }, + "node_modules/vite/node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, "node_modules/vite/node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -12531,6 +12528,7 @@ "integrity": "sha512-9qv4rlDiopXg4E69k+vMHjNN63YFMe9sZMrdlvKnCjlCRWeCBswPPMPUfx+ipsAWq1LXHe70RcbaHdJJpS6hyQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "archiver-utils": "^3.0.4", "compress-commons": "^4.1.2", @@ -12546,6 +12544,7 @@ "integrity": "sha512-KVgf4XQVrTjhyWmx6cte4RxonPLR9onExufI1jhvw/MQ4BB6IsZD5gT8Lq+u/+pRkWna/6JoHpiQioaqFP5Rzw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "glob": "^7.2.3", "graceful-fs": "^4.2.0", diff --git a/package.json b/package.json index a3979a5..bd32b08 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,8 @@ "type": "module", "main": "dist-electron/main.js", "scripts": { - "dev": "npm-run-all --parallel transpile:electron dev:react dev:electron", + "banner": "node banner.js", + "dev": "npm-run-all banner --parallel transpile:electron dev:react dev:electron", "dev:react": "vite", "dev:electron": "npm run build && cross-env NODE_ENV=development electron --inspect=5858 .", "prod:electron": "npm run build && cross-env NODE_ENV=production electron .", @@ -24,6 +25,7 @@ "axios": "^1.13.2", "chalk": "^5.6.2", "electron-store": "^11.0.2", + "figlet": "^1.9.4", "https": "^1.0.0", "lucide-react": "^0.552.0", "luxon": "^3.7.2", diff --git a/src/electron/api/axiosClient.ts b/src/electron/api/axiosClient.ts index 7928050..fbed677 100644 --- a/src/electron/api/axiosClient.ts +++ b/src/electron/api/axiosClient.ts @@ -38,14 +38,33 @@ api.interceptors.request.use( ); // --- Response Interceptor --- +// api.interceptors.response.use( +// (response: AxiosResponse) => response.data, +// async (error) => { +// console.error('[Axios Error]', error.status); +// if (error.status === 401 || 403) { +// console.warn('Token expired β€” trigger refresh logic if needed'); +// // sendTokenExpired(); +// } +// return Promise.reject(error); +// } +// ); + api.interceptors.response.use( (response: AxiosResponse) => response.data, async (error) => { - // console.error('[Axios Error]', error.message); - if (error.response?.status === 401 || 403) { + + console.log(error , "Line 46") + const status = error?.response?.status; + + console.error('[Axios Error]', status); + + // Only logout when token actually expired + if (status === 401 || status === 403) { console.warn('Token expired β€” trigger refresh logic if needed'); sendTokenExpired(); } + return Promise.reject(error); } ); diff --git a/src/electron/ipc/ipcHandler.ts b/src/electron/ipc/ipcHandler.ts index 8d1b67f..3c31f29 100644 --- a/src/electron/ipc/ipcHandler.ts +++ b/src/electron/ipc/ipcHandler.ts @@ -345,6 +345,8 @@ ipcMain.handle("create-leave-request", async (event, payload) => { let message = "Unknown error"; + console.log(error.response) + if (error.response) { console.log("Status:", error.response.status); console.log("Message:", error.response.statusText); @@ -405,11 +407,10 @@ ipcMain.handle("get-payslips", async (event, vaId: string) => { console.log("get-payslips", vaId) try { const response = await api.get(`/paySlip/${vaId}`); - - + console.log(response.data , "Line 409") return { success: true, - data: response.data?.data || [], + data: response.data || [], }; } catch (error: any) { let message = "Unknown error occurred"; @@ -439,10 +440,10 @@ ipcMain.handle("get-leave-list", async () => { const res = await api.get("/leaves/all"); console.log("/leaves/all", res.data); - return { - success: true, - data: res.data, - }; + return { + success: true, + data: res.data, + }; } catch (error: any) { let message = "Unknown error occurred"; @@ -468,10 +469,10 @@ ipcMain.handle("get-adjustments-list", async (event, vaId: string) => { const res = await api.get(`/timesheet/adjustments/list?vaId=${vaId}`); console.log("/timesheet/adjustments/list", res.data); - return { - success: true, - data: res.data, - }; + return { + success: true, + data: res.data, + }; } catch (error: any) { let message = "Unknown error occurred"; diff --git a/src/electron/main.ts b/src/electron/main.ts index 943d6cc..2e6f53d 100644 --- a/src/electron/main.ts +++ b/src/electron/main.ts @@ -68,7 +68,7 @@ app.on("ready", async () => { show: true, skipTaskbar: true, webPreferences: { - devTools: true, + devTools: false, } }); @@ -164,17 +164,17 @@ app.on("ready", async () => { }); -// app.on('browser-window-focus', () => { -// globalShortcut.register('CommandOrControl+R', () => { -// // Do nothing; disables reload -// }); -// globalShortcut.register('F5', () => { -// // Do nothing; disables reload -// }); -// globalShortcut.register('CommandOrControl+Shift+I', () => { -// // Do nothing; disables DevTools -// }); -// }); +app.on('browser-window-focus', () => { + globalShortcut.register('CommandOrControl+R', () => { + // Do nothing; disables reload + }); + globalShortcut.register('F5', () => { + // Do nothing; disables reload + }); + globalShortcut.register('CommandOrControl+Shift+I', () => { + // Do nothing; disables DevTools + }); +}); // app.on('browser-window-blur', () => { // globalShortcut.unregisterAll(); diff --git a/src/ui/hooks/useActiveAppTracker.tsx b/src/ui/hooks/useActiveAppTracker.tsx index a7620d1..3099d19 100644 --- a/src/ui/hooks/useActiveAppTracker.tsx +++ b/src/ui/hooks/useActiveAppTracker.tsx @@ -8,14 +8,12 @@ interface DailyHours { remaining: string; } - - export const useActiveAppTracker = ( isTracking: boolean, activeProjectLogId: string | null, projectId: string | null, projectName: string | null, - onLimitExceeded?: () => void // Callback when limit is reached + onLimitExceeded?: () => void ) => { const dispatch = useDispatch(); const lastActiveRef = useRef(null); @@ -24,8 +22,9 @@ export const useActiveAppTracker = ( const intervalIdRef = useRef(null); const finalizeTrackingRef = useRef<(() => Promise) | null>(null); const limitCheckedRef = useRef(false); + const isStoppingRef = useRef(false); // βœ… Flag to prevent new requests - const canSend = !!(activeProjectLogId && projectId); + const canSend = !!(activeProjectLogId && projectId && !isStoppingRef.current); // βœ… Parse time string to minutes const parseTimeToMinutes = (timeStr: string): number => { @@ -53,7 +52,6 @@ export const useActiveAppTracker = ( exceeded: remainingMins <= 0 }); - // If remaining time is 0 or negative, limit is exceeded if (remainingMins <= 0) { return true; } @@ -61,6 +59,7 @@ export const useActiveAppTracker = ( return false; }; + // βœ… Send activity log (POST for new, PATCH for update) const sendActivityLog = async ( projectLogId: string, projectId: string, @@ -68,8 +67,14 @@ export const useActiveAppTracker = ( appName: string, isNew: boolean ) => { + // βœ… CRITICAL: Block all requests when stopping + if (isStoppingRef.current) { + console.log("🚫 Stopping in progress β€” blocking activity log"); + return null; + } + if (!canSend) { - console.log("🚫 Skipping API β€” missing activeProjectLogId or projectId"); + console.log("🚫 Skipping API β€” missing required IDs"); return null; } @@ -99,20 +104,18 @@ export const useActiveAppTracker = ( // Store the log ID for future updates if (isNew && res?.data?._id) { - console.log("res?.data?._id", res?.data?._id) lastLogIdRef.current = res.data._id; + console.log("πŸ’Ύ Stored log ID:", res.data._id); } // βœ… Check daily limit after every API call if (res?.dailyHours) { - console.log("res?.data?.dailyHours", res?.dailyHours) - const limitExceeded = checkDailyLimit(res?.dailyHours); + const limitExceeded = checkDailyLimit(res.dailyHours); if (limitExceeded && !limitCheckedRef.current) { limitCheckedRef.current = true; - console.warn("🚨 Daily limit exceeded! Stopping tracking..."); + console.warn("🚨 Daily limit exceeded!"); - // Trigger stop tracking callback if (onLimitExceeded) { setTimeout(() => { onLimitExceeded(); @@ -128,54 +131,69 @@ export const useActiveAppTracker = ( } }; - // βœ… Final PATCH before stopping + // βœ… Stop the interval immediately + const stopInterval = useCallback(() => { + console.log("πŸ›‘ Stopping activity tracking interval..."); + if (intervalIdRef.current) { + clearInterval(intervalIdRef.current); + intervalIdRef.current = null; + console.log("βœ… Interval cleared"); + } + }, []); + + // βœ… Send final PATCH before stopping (called by handleStopTracking) const sendFinalPatch = useCallback(async () => { - if (!canSend) { - console.log("🚫 Skipping final PATCH β€” no active project log ID"); + console.log("=".repeat(60)); + console.log("πŸ›‘ FINAL PATCH INITIATED"); + console.log("=".repeat(60)); + + // βœ… STEP 1: Set stopping flag IMMEDIATELY + isStoppingRef.current = true; + console.log("πŸ”’ Stopping flag set β€” no new requests allowed"); + + // βœ… STEP 2: Stop the interval IMMEDIATELY + stopInterval(); + + if (!activeProjectLogId || !projectId) { + console.log("⚠️ Skipping final PATCH β€” no active project log ID"); return; } - console.log("=".repeat(60)); - console.log("πŸ›‘ FINAL PATCH INITIATED - Recording last activity"); - console.log("=".repeat(60)); - + // βœ… STEP 3: Send ONE final PATCH for the last active window if (lastLogIdRef.current && lastTitleRef.current && lastActiveRef.current) { try { console.log("πŸ“Š Final Activity Details:"); - console.log(` β€’ Window Title: ${lastTitleRef.current}`); - console.log(` β€’ App Name: ${lastActiveRef.current.owner.name}`); + console.log(` β€’ Window: ${lastTitleRef.current}`); + console.log(` β€’ App: ${lastActiveRef.current.owner.name}`); console.log(` β€’ Log ID: ${lastLogIdRef.current}`); - console.log(` β€’ Project ID: ${projectId}`); + console.log(` β€’ Project: ${projectId}`); const result = await sendActivityLog( - activeProjectLogId!, - projectId!, + activeProjectLogId, + projectId, lastTitleRef.current, lastActiveRef.current.owner.name || "Unknown", - false // This is a PATCH (update), not a POST (new) + false // PATCH (update existing log) ); console.log("βœ… Final PATCH sent successfully!"); if (result?.dailyHours) { - console.log("πŸ“ˆ Final Daily Hours Summary:"); - console.log(` β€’ Today Total: ${result.dailyHours.todayTotal}`); - console.log(` β€’ Daily Limit: ${result.dailyHours.dailyLimit}`); + console.log("πŸ“ˆ Final Daily Hours:"); + console.log(` β€’ Today: ${result.dailyHours.todayTotal}`); + console.log(` β€’ Limit: ${result.dailyHours.dailyLimit}`); console.log(` β€’ Remaining: ${result.dailyHours.remaining}`); } } catch (error) { console.error("❌ Final PATCH failed:", error); - throw error; // Re-throw to let caller handle + throw error; } } else { console.log("ℹ️ No active window to finalize"); - console.log(" β€’ Last Log ID:", lastLogIdRef.current || "None"); - console.log(" β€’ Last Title:", lastTitleRef.current || "None"); - console.log(" β€’ Last Active Window:", lastActiveRef.current ? "Yes" : "No"); } - // Clean up all refs + // βœ… STEP 4: Clean up all refs console.log("🧹 Cleaning up tracking references..."); lastActiveRef.current = null; lastTitleRef.current = null; @@ -183,70 +201,88 @@ export const useActiveAppTracker = ( limitCheckedRef.current = false; console.log("βœ… Cleanup complete"); console.log("=".repeat(60)); - }, [activeProjectLogId, projectId, canSend]); + }, [activeProjectLogId, projectId, stopInterval]); + // βœ… Update ref whenever sendFinalPatch changes useEffect(() => { finalizeTrackingRef.current = sendFinalPatch; }, [sendFinalPatch]); + // βœ… Main tracking interval effect useEffect(() => { - // Reset limit check when tracking starts + // Reset flags when tracking starts if (isTracking) { limitCheckedRef.current = false; + isStoppingRef.current = false; + console.log("🟒 Tracking started β€” flags reset"); } if (!isTracking || !canSend) { - console.log("🟑 Tracking inactive or missing IDs β€” skipping tracker setup"); + console.log("🟑 Tracking inactive β€” cleaning up"); + stopInterval(); return; } console.log(`🟒 Starting active tracker for: ${projectName}`); const fetchActiveApp = async () => { + // βœ… Double-check stopping flag before each fetch + if (isStoppingRef.current) { + console.log("🚫 Stopping in progress β€” skipping fetch"); + return; + } + try { const details = (await window.electron.getActiveAppDetails()) as WindowInfo; if (!details || !details.id) return; - console.log("details" , details) - const title = details.title; const appName = details.owner.name; const prevTitle = lastTitleRef.current; const hasChanged = !prevTitle || prevTitle !== title; if (hasChanged) { + // PATCH previous window before creating new log if (lastLogIdRef.current && prevTitle) { - console.log("πŸ”„ Patching previous log:", prevTitle); + console.log("πŸ”„ Updating previous window:", prevTitle); await sendActivityLog(activeProjectLogId!, projectId!, prevTitle, appName, false); } - console.log("πŸ†• New title detected β†’ creating POST:", title); + // POST new window log + console.log("πŸ†• New window detected:", title); await sendActivityLog(activeProjectLogId!, projectId!, title, appName, true); + // Update refs and Redux lastActiveRef.current = details; lastTitleRef.current = title; dispatch(setActiveWindow({ window: details, projectId, projectName })); } else { - console.log("⏸ Same window, skipping log"); + console.log("⏸️ Same window, skipping"); } } catch (error) { - console.error("Failed to fetch active app:", error); + console.error("❌ Failed to fetch active app:", error); } }; + // Initial fetch fetchActiveApp(); + + // Set up interval (every 5 seconds) intervalIdRef.current = setInterval(fetchActiveApp, 5000); + // Cleanup on unmount return () => { console.log("🧹 Cleaning up tracker interval"); - if (intervalIdRef.current) { - clearInterval(intervalIdRef.current); - intervalIdRef.current = null; - } + stopInterval(); }; - }, [isTracking, activeProjectLogId]); + }, [isTracking, activeProjectLogId, projectId, projectName, dispatch, stopInterval]); return { finalizeTracking: finalizeTrackingRef.current, + stopInterval, + setIsStopping: (value: boolean) => { + isStoppingRef.current = value; + console.log(`πŸ”’ Stopping flag manually set to: ${value}`); + } }; }; \ No newline at end of file diff --git a/src/ui/layout/DashboardLayout.tsx b/src/ui/layout/DashboardLayout.tsx index 547fe9f..1359372 100644 --- a/src/ui/layout/DashboardLayout.tsx +++ b/src/ui/layout/DashboardLayout.tsx @@ -135,155 +135,10 @@ const DashboardLayout = () => { document.documentElement.setAttribute("data-theme", theme); }, [theme]); - // Create a ref to store the stop function so it can be called from the hook const stopTrackingRef = useRef<(() => Promise) | null>(null); const limitAlertShownRef = useRef(false); - // Define handleStopTracking FIRST - const handleStopTracking = useCallback(async () => { - if (loadingStop || loadingStart) return; - - if (!selectedProject) { - console.warn("No selected project to stop"); - return; - } - - // Reset alert flag when stopping - limitAlertShownRef.current = false; - - let currentStopTime = new Date().toISOString(); - const projectId = selectedProject.projectId; - - console.log(" Stop tracking initiated for:", selectedProject.projectName); - console.log(" Current elapsed time:", elapsedTime); - - setIsStopping(true); - setLoadingStop(true); - handleSocketDisconnect(); - - // STEP 1: Clear timer FIRST to prevent further client-side updates - if (timerRef.current) { - clearInterval(timerRef.current); - timerRef.current = null; - console.log("Timer cleared"); - } - - // STEP 2: Send final PATCH with last active window data - if (stopTrackingRef.current) { - try { - console.log(" Sending final PATCH to record last activity..."); - await stopTrackingRef.current(); - console.log(" Final tracking data sent successfully"); - } catch (error) { - console.error(" Error sending final tracking data:", error); - } - } - - // STEP 3: Send LOGOUT to backend - try { - const payload = { - vaId: projectSummary.vaId, - projectId: projectId, - type: "LOGOUT", - time: currentStopTime - }; - - console.log("πŸ“‘ Sending LOGOUT request:", payload); - const res = await window.electron.stopProjectTracking(payload); - console.log(" LOGOUT successful:", res); - } catch (error) { - console.error(" Failed to send LOGOUT:", error); - } - - // STEP 4: Update Redux tracking state to stop tracking - console.log("πŸ”„ Updating Redux state to stop tracking..."); - dispatch( - stopTrackingReducer({ - projectId, - }) - ); - - // Allow React to process the state update - await new Promise(resolve => setTimeout(resolve, 50)); - - // STEP 5: Refresh project list to get updated work hours from server - try { - console.log("πŸ”„ Refreshing project list..."); - const projectListRes = await window.electron.getProjectList(); - console.log("πŸ“Š Updated project list:", projectListRes); - - if (projectListRes?.success && Array.isArray(projectListRes.data)) { - // Update projects data - dispatch(setProjectsDataSlice(projectListRes.data)); - - // Update project summary - dispatch( - setProjectSummarySlice({ - totalProjects: projectListRes.totalProjects || 0, - activeProjects: projectListRes.activeProjects || 0, - awayProjects: projectListRes.awayProjects || 0, - totalWorkTime: projectListRes.totalWorkTime || "0h 0m 0s", - totalWorkMs: projectListRes.totalWorkMs || 0, - vaName: projectListRes.vaName || "", - vaId: projectListRes.vaId || "", - }) - ); - - // Update selected project with fresh data - const updatedProject = projectListRes.data.find( - (p: Project) => p.projectId === projectId - ); - - if (updatedProject) { - dispatch(setSelectedProjectSlice(updatedProject)); - - // CRITICAL FIX: Use server time instead of client elapsedTime - const serverElapsedTime = parseTimeStringToSeconds(updatedProject.totalWorkTime); - - console.log("πŸ”„ Syncing client time with server time:", { - serverTime: updatedProject.totalWorkTime, - serverElapsedSeconds: serverElapsedTime, - previousClientTime: elapsedTime, - difference: serverElapsedTime - elapsedTime - }); - - // Force update the tracking map with server time - dispatch( - updateProjectTracking({ - projectId: updatedProject.projectId, - data: { - elapsedTime: serverElapsedTime, - accumulatedTime: serverElapsedTime, - isTracking: false, - isPaused: false, - startTime: null, - endTime: Date.now(), - pauseStartTime: null, - totalPausedTime: 0 - } - }) - ); - - console.log("βœ… Selected project updated with server time"); - } - } - - // STEP 6: Update UI (window restore) - await window.electron.toggleCloseBtn(true); - await window.electron.resizeWindow(500, 600); - toggleWindowSize.current = true; - - } catch (error) { - console.error("❌ Error refreshing project list:", error); - } finally { - // Clear loading states - setLoadingStop(false); - setIsStopping(false); - console.log("πŸŽ‰ TRACKING STOPPED SUCCESSFULLY"); - } - }, [selectedProject, projectSummary, elapsedTime, dispatch]); - // NOW define handleLimitExceeded using the defined handleStopTracking const handleLimitExceeded = useCallback(async () => { console.log("🚨 LIMIT EXCEEDED - Showing alert (not stopping)"); @@ -316,7 +171,7 @@ const DashboardLayout = () => { }, [selectedProject]); // Initialize useActiveAppTracker and store finalizeTracking in ref - const { finalizeTracking } = useActiveAppTracker( + const { finalizeTracking, setIsStopping: setIsStoppingInTracker } = useActiveAppTracker( isTracking, activeProjectLogId, selectedProject?.projectId ?? null, @@ -324,6 +179,186 @@ const DashboardLayout = () => { handleLimitExceeded ); + // Define handleStopTracking FIRST + const handleStopTracking = useCallback(async () => { + if (loadingStop || loadingStart) { + console.log("⏸️ Already processing, skipping..."); + return; + } + + if (!selectedProject) { + console.warn("⚠️ No selected project to stop"); + return; + } + + console.log("=".repeat(70)); + console.log("πŸ›‘ STOP TRACKING INITIATED"); + console.log("=".repeat(70)); + console.log(`πŸ“¦ Project: ${selectedProject.projectName}`); + console.log(`⏱️ Elapsed Time: ${elapsedTime}s`); + + // Reset alert flag when stopping + limitAlertShownRef.current = false; + + const currentStopTime = new Date().toISOString(); + const projectId = selectedProject.projectId; + + // βœ… CRITICAL: Set stopping flag IMMEDIATELY to block all new tab tracking + console.log("πŸ”’ Setting stopping flag..."); + if (setIsStoppingInTracker) { + setIsStoppingInTracker(true); + } + + setIsStopping(true); + setLoadingStop(true); + handleSocketDisconnect(); + + // STEP 1: Clear local timer to prevent further client-side updates + console.log("⏹️ STEP 1: Clearing local timer..."); + if (timerRef.current) { + clearInterval(timerRef.current); + timerRef.current = null; + console.log("βœ… Timer cleared"); + } + + // STEP 2: Send final PATCH with last active window data + console.log("πŸ“€ STEP 2: Sending final activity tracking..."); + if (stopTrackingRef.current) { + try { + await stopTrackingRef.current(); // This calls sendFinalPatch() in the hook + console.log("βœ… Final activity tracking completed"); + } catch (error) { + console.error("❌ Error during final tracking:", error); + } + } else { + console.log("⚠️ No tracking ref available"); + } + + // STEP 3: Send LOGOUT to backend + console.log("πŸšͺ STEP 3: Sending LOGOUT request..."); + try { + const payload = { + vaId: projectSummary.vaId, + projectId: projectId, + type: "LOGOUT", + time: currentStopTime + }; + + console.log("πŸ“‘ Logout payload:", payload); + const res = await window.electron.stopProjectTracking(payload); + console.log("βœ… LOGOUT successful:", res); + } catch (error) { + console.error("❌ LOGOUT failed:", error); + } + + // STEP 4: Update Redux tracking state + console.log("πŸ”„ STEP 4: Updating Redux state..."); + dispatch( + stopTrackingReducer({ + projectId, + }) + ); + + // STEP 6: Update UI (restore window) + console.log("πŸͺŸ STEP 6: Restoring window..."); + await window.electron.toggleCloseBtn(true); + await window.electron.resizeWindow(500, 600); + toggleWindowSize.current = true; + console.log("βœ… Window restored"); + + // Allow React to process the state update + await new Promise(resolve => setTimeout(resolve, 50)); + + // STEP 5: Refresh project list to get updated work hours from server + console.log("πŸ“Š STEP 5: Refreshing project list..."); + try { + const projectListRes = await window.electron.getProjectList(); + console.log("βœ… Project list fetched:", projectListRes); + + if (projectListRes?.success && Array.isArray(projectListRes.data)) { + // Update projects data + dispatch(setProjectsDataSlice(projectListRes.data)); + + // Update project summary + dispatch( + setProjectSummarySlice({ + totalProjects: projectListRes.totalProjects || 0, + activeProjects: projectListRes.activeProjects || 0, + awayProjects: projectListRes.awayProjects || 0, + totalWorkTime: projectListRes.totalWorkTime || "0h 0m 0s", + totalWorkMs: projectListRes.totalWorkMs || 0, + vaName: projectListRes.vaName || "", + vaId: projectListRes.vaId || "", + }) + ); + + // Update selected project with fresh data from server + const updatedProject = projectListRes.data.find( + (p: Project) => p.projectId === projectId + ); + + if (updatedProject) { + dispatch(setSelectedProjectSlice(updatedProject)); + + // Sync client time with server time + const serverElapsedTime = parseTimeStringToSeconds(updatedProject.totalWorkTime); + + console.log("πŸ”„ Syncing with server time:", { + serverTime: updatedProject.totalWorkTime, + serverSeconds: serverElapsedTime, + clientSeconds: elapsedTime, + difference: serverElapsedTime - elapsedTime + }); + + // Force update the tracking map with server time + dispatch( + updateProjectTracking({ + projectId: updatedProject.projectId, + data: { + elapsedTime: serverElapsedTime, + accumulatedTime: serverElapsedTime, + isTracking: false, + isPaused: false, + startTime: null, + endTime: Date.now(), + pauseStartTime: null, + totalPausedTime: 0 + } + }) + ); + + console.log("βœ… Project synced with server"); + } + } + + + + } catch (error) { + console.error("❌ Error refreshing project list:", error); + } finally { + // Clear loading states + setLoadingStop(false); + setIsStopping(false); + + // βœ… Reset stopping flag for next session + if (setIsStoppingInTracker) { + setIsStoppingInTracker(false); + } + + console.log("=".repeat(70)); + console.log("πŸŽ‰ TRACKING STOPPED SUCCESSFULLY"); + console.log("=".repeat(70)); + } + }, [ + selectedProject, + projectSummary, + elapsedTime, + dispatch, + loadingStop, + loadingStart, + setIsStoppingInTracker + ]); + // Update the ref whenever finalizeTracking changes useEffect(() => { stopTrackingRef.current = finalizeTracking; @@ -362,7 +397,7 @@ const DashboardLayout = () => { return () => { console.log("🧹 Cleaning token-expired listener"); }; - }, [isTracking, handleStopTracking]); + }, [isTracking]); const handleLogout = async () => { @@ -553,7 +588,7 @@ const DashboardLayout = () => { if (!selectedProject?.projectId) return console.log(selectedProject?.projectId, "SelectedProject ID") - socketRef.current = io("https://daniela-nonprofessed-boastfully.ngrok-free.app", { + socketRef.current = io("https://quality-friendly-goldfish.ngrok-free.app", { transports: ["websocket"], secure: true, rejectUnauthorized: false, @@ -585,7 +620,7 @@ const DashboardLayout = () => { // socketRef.current?.emit("getVisibleApps", { token: await token, apps }); // }); - socketRef.current.on("startSendAppsDetails", async ({projId}) => { + socketRef.current.on("startSendAppsDetails", async ({ projId }) => { if (projId !== selectedProject?.projectId) return; console.log("▢️ startSendAppsDetails received"); @@ -609,7 +644,7 @@ const DashboardLayout = () => { }, 5000); }); - socketRef.current.on("stopSendAppsDetails", async ({projId}) => { + socketRef.current.on("stopSendAppsDetails", async ({ projId }) => { if (projId !== selectedProject?.projectId) return; console.log("⏹ stopSendAppsDetails received"); diff --git a/src/ui/pages/LeaveAndAdjustments/LeaveAndAdjustments.tsx b/src/ui/pages/LeaveAndAdjustments/LeaveAndAdjustments.tsx index e6e728f..9c94649 100644 --- a/src/ui/pages/LeaveAndAdjustments/LeaveAndAdjustments.tsx +++ b/src/ui/pages/LeaveAndAdjustments/LeaveAndAdjustments.tsx @@ -43,7 +43,7 @@ const LeaveAndAdjustments: React.FC = () => { const navigate = useNavigate(); const { projectSummary } = useSelector((state: any) => state.projects); -console.log("projectSummary46" , projectSummary) + console.log("projectSummary46", projectSummary) // Tabs state const [activeTab, setActiveTab] = useState<"leave" | "adjustments">("leave"); @@ -95,18 +95,25 @@ console.log("projectSummary46" , projectSummary) // Combined refresh function const handleRefresh = async () => { - if (activeTab === "leave") { - await fetchLeaves(); - } else { - await fetchAdjustments(); - } + // if (activeTab === "leave") { + // await fetchLeaves(); + // } else { + // await fetchAdjustments(); + // } + + fetchLeaves(); + setTimeout(() => { + fetchAdjustments(); + }, 0); setLastRefreshed(new Date()); }; // Initial data fetch useEffect(() => { fetchLeaves(); - fetchAdjustments(); + setTimeout(() => { + fetchAdjustments(); + }, 0); setLastRefreshed(new Date()); }, []); diff --git a/src/ui/pages/LeaveAndAdjustments/tabs/SickLeaveTab.tsx b/src/ui/pages/LeaveAndAdjustments/tabs/SickLeaveTab.tsx index 8ac6d6f..e6b9215 100644 --- a/src/ui/pages/LeaveAndAdjustments/tabs/SickLeaveTab.tsx +++ b/src/ui/pages/LeaveAndAdjustments/tabs/SickLeaveTab.tsx @@ -126,6 +126,33 @@ const SickLeaveTab: React.FC<{ reader.readAsDataURL(file); }); + useEffect(() => { + const editor = quillRef.current?.getEditor(); + + if (!editor) return; + + editor.getModule("clipboard").addMatcher(Node.ELEMENT_NODE, (node: any, delta: any) => { + return delta; + }); + + editor.root.addEventListener("paste", async (e: any) => { + const items = e.clipboardData?.items; + + if (!items) return; + + for (const item of items) { + if (item.type.indexOf("image") === 0) { + const file = item.getAsFile(); + const base64 = await convertToBase64(file); + + const range = editor.getSelection(); + editor.insertEmbed(range.index, "image", base64); + } + } + }); + }, []); + + const validateLeaveForm = (data: LeaveFormData): Partial => { const errors: Partial = {}; @@ -161,7 +188,6 @@ const SickLeaveTab: React.FC<{ toDate: "", comment: "" }; - setSickLeave(emptyForm); setSickErrors({}); diff --git a/src/ui/pages/PaySlips/PaysSlips.tsx b/src/ui/pages/PaySlips/PaysSlips.tsx index b54e3c9..d3d9ca5 100644 --- a/src/ui/pages/PaySlips/PaysSlips.tsx +++ b/src/ui/pages/PaySlips/PaysSlips.tsx @@ -36,6 +36,8 @@ const PaysSlips = () => { return; } + console.log(response , "getPayslips") + // Extract payrolls array from first index const payrolls = response[0]?.payrolls || []; diff --git a/src/ui/pages/Vpn/VpnGuard.tsx b/src/ui/pages/Vpn/VpnGuard.tsx new file mode 100644 index 0000000..5032cb9 --- /dev/null +++ b/src/ui/pages/Vpn/VpnGuard.tsx @@ -0,0 +1,54 @@ +import React, { useEffect, useState } from "react"; + +interface Props { + children: React.ReactNode; +} + +const VpnGuard: React.FC = ({ children }) => { + const [checking, setChecking] = useState(true); + const [vpnConnected, setVpnConnected] = useState(true); + +// const checkVPN = async () => { +// try { +// const res = await window.electron.checkVpnConnection(); +// setVpnConnected(res?.success); +// } catch { +// setVpnConnected(false); +// } finally { +// setChecking(false); +// } +// }; + + useEffect(() => { + // checkVPN(); + }, []); + + if (checking) { + return ( +
+ + Checking VPN... +
+ ); + } + + if (!vpnConnected) { + return ( +
+
+

VPN Required

+

Please connect to your company VPN to continue.

+ + +
+
+ ); + } + + return <>{children}; +}; + +export default VpnGuard; diff --git a/types.d.ts b/types.d.ts index 51df381..1c693fb 100644 --- a/types.d.ts +++ b/types.d.ts @@ -1,3 +1,13 @@ +declare module "quill"; +declare module "quill-image-resize-module"; +declare module "quill-image-drop-module"; + +declare module "quill-image-resize-module-react" { + const ImageResize: any; + export default ImageResize; +} + + type Statistics = { cpuUsage: number; ramUsage: number; @@ -144,14 +154,16 @@ interface Window { vaId: string; projectId: string; type: string; + time:string }) => Promise; stopProjectTracking: (data: { vaId: string; projectId: string; type: string; + time:string }) => Promise; trackingTabsOpeningClosing: (data: { - id?: string; // optional, only present if updating + id?: string; logId: string; projectId: string; title: string;