Prakhar Singh commited on
Commit
8811e47
·
1 Parent(s): 2636d69

DashBoard and Quize Cereated

Browse files
Frontend/package-lock.json CHANGED
@@ -12,11 +12,13 @@
12
  "@splinetool/runtime": "^1.11.2",
13
  "@tailwindcss/vite": "^4.1.17",
14
  "clsx": "^2.1.1",
 
15
  "framer-motion": "^12.23.24",
16
  "lucide-react": "^0.553.0",
17
  "react": "^19.2.0",
18
  "react-dom": "^19.2.0",
19
  "react-router-dom": "^7.9.5",
 
20
  "tailwind-merge": "^3.4.0",
21
  "tailwindcss": "^4.1.17"
22
  },
@@ -1025,6 +1027,32 @@
1025
  "node": ">= 8"
1026
  }
1027
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1028
  "node_modules/@rolldown/pluginutils": {
1029
  "version": "1.0.0-beta.43",
1030
  "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.43.tgz",
@@ -1349,6 +1377,18 @@
1349
  "semver-compare": "^1.0.0"
1350
  }
1351
  },
 
 
 
 
 
 
 
 
 
 
 
 
1352
  "node_modules/@tailwindcss/node": {
1353
  "version": "4.1.17",
1354
  "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.17.tgz",
@@ -1651,6 +1691,69 @@
1651
  "@babel/types": "^7.28.2"
1652
  }
1653
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1654
  "node_modules/@types/estree": {
1655
  "version": "1.0.8",
1656
  "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
@@ -1678,7 +1781,7 @@
1678
  "version": "19.2.2",
1679
  "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.2.tgz",
1680
  "integrity": "sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA==",
1681
- "dev": true,
1682
  "license": "MIT",
1683
  "dependencies": {
1684
  "csstype": "^3.0.2"
@@ -1694,6 +1797,12 @@
1694
  "@types/react": "^19.2.0"
1695
  }
1696
  },
 
 
 
 
 
 
1697
  "node_modules/@typescript-eslint/eslint-plugin": {
1698
  "version": "8.46.3",
1699
  "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.46.3.tgz",
@@ -2249,7 +2358,134 @@
2249
  "version": "3.1.3",
2250
  "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
2251
  "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
2252
- "dev": true,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2253
  "license": "MIT"
2254
  },
2255
  "node_modules/debug": {
@@ -2270,6 +2506,12 @@
2270
  }
2271
  }
2272
  },
 
 
 
 
 
 
2273
  "node_modules/deep-is": {
2274
  "version": "0.1.4",
2275
  "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
@@ -2306,6 +2548,16 @@
2306
  "node": ">=10.13.0"
2307
  }
2308
  },
 
 
 
 
 
 
 
 
 
 
2309
  "node_modules/esbuild": {
2310
  "version": "0.25.12",
2311
  "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz",
@@ -2547,6 +2799,12 @@
2547
  "node": ">=0.10.0"
2548
  }
2549
  },
 
 
 
 
 
 
2550
  "node_modules/fast-deep-equal": {
2551
  "version": "3.1.3",
2552
  "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
@@ -2782,6 +3040,16 @@
2782
  "node": ">= 4"
2783
  }
2784
  },
 
 
 
 
 
 
 
 
 
 
2785
  "node_modules/import-fresh": {
2786
  "version": "3.3.1",
2787
  "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
@@ -2809,6 +3077,15 @@
2809
  "node": ">=0.8.19"
2810
  }
2811
  },
 
 
 
 
 
 
 
 
 
2812
  "node_modules/is-extglob": {
2813
  "version": "2.1.1",
2814
  "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
@@ -3550,6 +3827,13 @@
3550
  "react": "^19.2.0"
3551
  }
3552
  },
 
 
 
 
 
 
 
3553
  "node_modules/react-merge-refs": {
3554
  "version": "2.1.1",
3555
  "resolved": "https://registry.npmjs.org/react-merge-refs/-/react-merge-refs-2.1.1.tgz",
@@ -3560,6 +3844,29 @@
3560
  "url": "https://github.com/sponsors/gregberge"
3561
  }
3562
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3563
  "node_modules/react-refresh": {
3564
  "version": "0.18.0",
3565
  "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.18.0.tgz",
@@ -3608,6 +3915,57 @@
3608
  "react-dom": ">=18"
3609
  }
3610
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3611
  "node_modules/resolve-from": {
3612
  "version": "4.0.0",
3613
  "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
@@ -3815,6 +4173,12 @@
3815
  "integrity": "sha512-kH5pKeIIBPQXAOni2AiY/Cu/NKdkFREdpH+TLdM0g6WA7RriCv0kPLgP731ady67MhTAqrVG/4mnEeibVuCJcg==",
3816
  "license": "MIT"
3817
  },
 
 
 
 
 
 
3818
  "node_modules/tinyglobby": {
3819
  "version": "0.2.15",
3820
  "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
@@ -3991,6 +4355,37 @@
3991
  "punycode": "^2.1.0"
3992
  }
3993
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3994
  "node_modules/vite": {
3995
  "version": "7.2.2",
3996
  "resolved": "https://registry.npmjs.org/vite/-/vite-7.2.2.tgz",
 
12
  "@splinetool/runtime": "^1.11.2",
13
  "@tailwindcss/vite": "^4.1.17",
14
  "clsx": "^2.1.1",
15
+ "dayjs": "^1.11.19",
16
  "framer-motion": "^12.23.24",
17
  "lucide-react": "^0.553.0",
18
  "react": "^19.2.0",
19
  "react-dom": "^19.2.0",
20
  "react-router-dom": "^7.9.5",
21
+ "recharts": "^3.4.1",
22
  "tailwind-merge": "^3.4.0",
23
  "tailwindcss": "^4.1.17"
24
  },
 
1027
  "node": ">= 8"
1028
  }
1029
  },
1030
+ "node_modules/@reduxjs/toolkit": {
1031
+ "version": "2.10.1",
1032
+ "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.10.1.tgz",
1033
+ "integrity": "sha512-/U17EXQ9Do9Yx4DlNGU6eVNfZvFJfYpUtRRdLf19PbPjdWBxNlxGZXywQZ1p1Nz8nMkWplTI7iD/23m07nolDA==",
1034
+ "license": "MIT",
1035
+ "dependencies": {
1036
+ "@standard-schema/spec": "^1.0.0",
1037
+ "@standard-schema/utils": "^0.3.0",
1038
+ "immer": "^10.2.0",
1039
+ "redux": "^5.0.1",
1040
+ "redux-thunk": "^3.1.0",
1041
+ "reselect": "^5.1.0"
1042
+ },
1043
+ "peerDependencies": {
1044
+ "react": "^16.9.0 || ^17.0.0 || ^18 || ^19",
1045
+ "react-redux": "^7.2.1 || ^8.1.3 || ^9.0.0"
1046
+ },
1047
+ "peerDependenciesMeta": {
1048
+ "react": {
1049
+ "optional": true
1050
+ },
1051
+ "react-redux": {
1052
+ "optional": true
1053
+ }
1054
+ }
1055
+ },
1056
  "node_modules/@rolldown/pluginutils": {
1057
  "version": "1.0.0-beta.43",
1058
  "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.43.tgz",
 
1377
  "semver-compare": "^1.0.0"
1378
  }
1379
  },
1380
+ "node_modules/@standard-schema/spec": {
1381
+ "version": "1.0.0",
1382
+ "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.0.0.tgz",
1383
+ "integrity": "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==",
1384
+ "license": "MIT"
1385
+ },
1386
+ "node_modules/@standard-schema/utils": {
1387
+ "version": "0.3.0",
1388
+ "resolved": "https://registry.npmjs.org/@standard-schema/utils/-/utils-0.3.0.tgz",
1389
+ "integrity": "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==",
1390
+ "license": "MIT"
1391
+ },
1392
  "node_modules/@tailwindcss/node": {
1393
  "version": "4.1.17",
1394
  "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.17.tgz",
 
1691
  "@babel/types": "^7.28.2"
1692
  }
1693
  },
1694
+ "node_modules/@types/d3-array": {
1695
+ "version": "3.2.2",
1696
+ "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.2.tgz",
1697
+ "integrity": "sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw==",
1698
+ "license": "MIT"
1699
+ },
1700
+ "node_modules/@types/d3-color": {
1701
+ "version": "3.1.3",
1702
+ "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz",
1703
+ "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==",
1704
+ "license": "MIT"
1705
+ },
1706
+ "node_modules/@types/d3-ease": {
1707
+ "version": "3.0.2",
1708
+ "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz",
1709
+ "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==",
1710
+ "license": "MIT"
1711
+ },
1712
+ "node_modules/@types/d3-interpolate": {
1713
+ "version": "3.0.4",
1714
+ "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz",
1715
+ "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==",
1716
+ "license": "MIT",
1717
+ "dependencies": {
1718
+ "@types/d3-color": "*"
1719
+ }
1720
+ },
1721
+ "node_modules/@types/d3-path": {
1722
+ "version": "3.1.1",
1723
+ "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.1.tgz",
1724
+ "integrity": "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==",
1725
+ "license": "MIT"
1726
+ },
1727
+ "node_modules/@types/d3-scale": {
1728
+ "version": "4.0.9",
1729
+ "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.9.tgz",
1730
+ "integrity": "sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==",
1731
+ "license": "MIT",
1732
+ "dependencies": {
1733
+ "@types/d3-time": "*"
1734
+ }
1735
+ },
1736
+ "node_modules/@types/d3-shape": {
1737
+ "version": "3.1.7",
1738
+ "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.7.tgz",
1739
+ "integrity": "sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg==",
1740
+ "license": "MIT",
1741
+ "dependencies": {
1742
+ "@types/d3-path": "*"
1743
+ }
1744
+ },
1745
+ "node_modules/@types/d3-time": {
1746
+ "version": "3.0.4",
1747
+ "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.4.tgz",
1748
+ "integrity": "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==",
1749
+ "license": "MIT"
1750
+ },
1751
+ "node_modules/@types/d3-timer": {
1752
+ "version": "3.0.2",
1753
+ "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz",
1754
+ "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==",
1755
+ "license": "MIT"
1756
+ },
1757
  "node_modules/@types/estree": {
1758
  "version": "1.0.8",
1759
  "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
 
1781
  "version": "19.2.2",
1782
  "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.2.tgz",
1783
  "integrity": "sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA==",
1784
+ "devOptional": true,
1785
  "license": "MIT",
1786
  "dependencies": {
1787
  "csstype": "^3.0.2"
 
1797
  "@types/react": "^19.2.0"
1798
  }
1799
  },
1800
+ "node_modules/@types/use-sync-external-store": {
1801
+ "version": "0.0.6",
1802
+ "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.6.tgz",
1803
+ "integrity": "sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==",
1804
+ "license": "MIT"
1805
+ },
1806
  "node_modules/@typescript-eslint/eslint-plugin": {
1807
  "version": "8.46.3",
1808
  "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.46.3.tgz",
 
2358
  "version": "3.1.3",
2359
  "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
2360
  "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
2361
+ "devOptional": true,
2362
+ "license": "MIT"
2363
+ },
2364
+ "node_modules/d3-array": {
2365
+ "version": "3.2.4",
2366
+ "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz",
2367
+ "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==",
2368
+ "license": "ISC",
2369
+ "dependencies": {
2370
+ "internmap": "1 - 2"
2371
+ },
2372
+ "engines": {
2373
+ "node": ">=12"
2374
+ }
2375
+ },
2376
+ "node_modules/d3-color": {
2377
+ "version": "3.1.0",
2378
+ "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz",
2379
+ "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==",
2380
+ "license": "ISC",
2381
+ "engines": {
2382
+ "node": ">=12"
2383
+ }
2384
+ },
2385
+ "node_modules/d3-ease": {
2386
+ "version": "3.0.1",
2387
+ "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz",
2388
+ "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==",
2389
+ "license": "BSD-3-Clause",
2390
+ "engines": {
2391
+ "node": ">=12"
2392
+ }
2393
+ },
2394
+ "node_modules/d3-format": {
2395
+ "version": "3.1.0",
2396
+ "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz",
2397
+ "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==",
2398
+ "license": "ISC",
2399
+ "engines": {
2400
+ "node": ">=12"
2401
+ }
2402
+ },
2403
+ "node_modules/d3-interpolate": {
2404
+ "version": "3.0.1",
2405
+ "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz",
2406
+ "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==",
2407
+ "license": "ISC",
2408
+ "dependencies": {
2409
+ "d3-color": "1 - 3"
2410
+ },
2411
+ "engines": {
2412
+ "node": ">=12"
2413
+ }
2414
+ },
2415
+ "node_modules/d3-path": {
2416
+ "version": "3.1.0",
2417
+ "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz",
2418
+ "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==",
2419
+ "license": "ISC",
2420
+ "engines": {
2421
+ "node": ">=12"
2422
+ }
2423
+ },
2424
+ "node_modules/d3-scale": {
2425
+ "version": "4.0.2",
2426
+ "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz",
2427
+ "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==",
2428
+ "license": "ISC",
2429
+ "dependencies": {
2430
+ "d3-array": "2.10.0 - 3",
2431
+ "d3-format": "1 - 3",
2432
+ "d3-interpolate": "1.2.0 - 3",
2433
+ "d3-time": "2.1.1 - 3",
2434
+ "d3-time-format": "2 - 4"
2435
+ },
2436
+ "engines": {
2437
+ "node": ">=12"
2438
+ }
2439
+ },
2440
+ "node_modules/d3-shape": {
2441
+ "version": "3.2.0",
2442
+ "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz",
2443
+ "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==",
2444
+ "license": "ISC",
2445
+ "dependencies": {
2446
+ "d3-path": "^3.1.0"
2447
+ },
2448
+ "engines": {
2449
+ "node": ">=12"
2450
+ }
2451
+ },
2452
+ "node_modules/d3-time": {
2453
+ "version": "3.1.0",
2454
+ "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz",
2455
+ "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==",
2456
+ "license": "ISC",
2457
+ "dependencies": {
2458
+ "d3-array": "2 - 3"
2459
+ },
2460
+ "engines": {
2461
+ "node": ">=12"
2462
+ }
2463
+ },
2464
+ "node_modules/d3-time-format": {
2465
+ "version": "4.1.0",
2466
+ "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz",
2467
+ "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==",
2468
+ "license": "ISC",
2469
+ "dependencies": {
2470
+ "d3-time": "1 - 3"
2471
+ },
2472
+ "engines": {
2473
+ "node": ">=12"
2474
+ }
2475
+ },
2476
+ "node_modules/d3-timer": {
2477
+ "version": "3.0.1",
2478
+ "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz",
2479
+ "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==",
2480
+ "license": "ISC",
2481
+ "engines": {
2482
+ "node": ">=12"
2483
+ }
2484
+ },
2485
+ "node_modules/dayjs": {
2486
+ "version": "1.11.19",
2487
+ "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.19.tgz",
2488
+ "integrity": "sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw==",
2489
  "license": "MIT"
2490
  },
2491
  "node_modules/debug": {
 
2506
  }
2507
  }
2508
  },
2509
+ "node_modules/decimal.js-light": {
2510
+ "version": "2.5.1",
2511
+ "resolved": "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz",
2512
+ "integrity": "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==",
2513
+ "license": "MIT"
2514
+ },
2515
  "node_modules/deep-is": {
2516
  "version": "0.1.4",
2517
  "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
 
2548
  "node": ">=10.13.0"
2549
  }
2550
  },
2551
+ "node_modules/es-toolkit": {
2552
+ "version": "1.41.0",
2553
+ "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.41.0.tgz",
2554
+ "integrity": "sha512-bDd3oRmbVgqZCJS6WmeQieOrzpl3URcWBUVDXxOELlUW2FuW+0glPOz1n0KnRie+PdyvUZcXz2sOn00c6pPRIA==",
2555
+ "license": "MIT",
2556
+ "workspaces": [
2557
+ "docs",
2558
+ "benchmarks"
2559
+ ]
2560
+ },
2561
  "node_modules/esbuild": {
2562
  "version": "0.25.12",
2563
  "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz",
 
2799
  "node": ">=0.10.0"
2800
  }
2801
  },
2802
+ "node_modules/eventemitter3": {
2803
+ "version": "5.0.1",
2804
+ "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz",
2805
+ "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==",
2806
+ "license": "MIT"
2807
+ },
2808
  "node_modules/fast-deep-equal": {
2809
  "version": "3.1.3",
2810
  "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
 
3040
  "node": ">= 4"
3041
  }
3042
  },
3043
+ "node_modules/immer": {
3044
+ "version": "10.2.0",
3045
+ "resolved": "https://registry.npmjs.org/immer/-/immer-10.2.0.tgz",
3046
+ "integrity": "sha512-d/+XTN3zfODyjr89gM3mPq1WNX2B8pYsu7eORitdwyA2sBubnTl3laYlBk4sXY5FUa5qTZGBDPJICVbvqzjlbw==",
3047
+ "license": "MIT",
3048
+ "funding": {
3049
+ "type": "opencollective",
3050
+ "url": "https://opencollective.com/immer"
3051
+ }
3052
+ },
3053
  "node_modules/import-fresh": {
3054
  "version": "3.3.1",
3055
  "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
 
3077
  "node": ">=0.8.19"
3078
  }
3079
  },
3080
+ "node_modules/internmap": {
3081
+ "version": "2.0.3",
3082
+ "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz",
3083
+ "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==",
3084
+ "license": "ISC",
3085
+ "engines": {
3086
+ "node": ">=12"
3087
+ }
3088
+ },
3089
  "node_modules/is-extglob": {
3090
  "version": "2.1.1",
3091
  "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
 
3827
  "react": "^19.2.0"
3828
  }
3829
  },
3830
+ "node_modules/react-is": {
3831
+ "version": "19.2.0",
3832
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.0.tgz",
3833
+ "integrity": "sha512-x3Ax3kNSMIIkyVYhWPyO09bu0uttcAIoecO/um/rKGQ4EltYWVYtyiGkS/3xMynrbVQdS69Jhlv8FXUEZehlzA==",
3834
+ "license": "MIT",
3835
+ "peer": true
3836
+ },
3837
  "node_modules/react-merge-refs": {
3838
  "version": "2.1.1",
3839
  "resolved": "https://registry.npmjs.org/react-merge-refs/-/react-merge-refs-2.1.1.tgz",
 
3844
  "url": "https://github.com/sponsors/gregberge"
3845
  }
3846
  },
3847
+ "node_modules/react-redux": {
3848
+ "version": "9.2.0",
3849
+ "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.2.0.tgz",
3850
+ "integrity": "sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g==",
3851
+ "license": "MIT",
3852
+ "dependencies": {
3853
+ "@types/use-sync-external-store": "^0.0.6",
3854
+ "use-sync-external-store": "^1.4.0"
3855
+ },
3856
+ "peerDependencies": {
3857
+ "@types/react": "^18.2.25 || ^19",
3858
+ "react": "^18.0 || ^19",
3859
+ "redux": "^5.0.0"
3860
+ },
3861
+ "peerDependenciesMeta": {
3862
+ "@types/react": {
3863
+ "optional": true
3864
+ },
3865
+ "redux": {
3866
+ "optional": true
3867
+ }
3868
+ }
3869
+ },
3870
  "node_modules/react-refresh": {
3871
  "version": "0.18.0",
3872
  "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.18.0.tgz",
 
3915
  "react-dom": ">=18"
3916
  }
3917
  },
3918
+ "node_modules/recharts": {
3919
+ "version": "3.4.1",
3920
+ "resolved": "https://registry.npmjs.org/recharts/-/recharts-3.4.1.tgz",
3921
+ "integrity": "sha512-35kYg6JoOgwq8sE4rhYkVWwa6aAIgOtT+Ob0gitnShjwUwZmhrmy7Jco/5kJNF4PnLXgt9Hwq+geEMS+WrjU1g==",
3922
+ "license": "MIT",
3923
+ "workspaces": [
3924
+ "www"
3925
+ ],
3926
+ "dependencies": {
3927
+ "@reduxjs/toolkit": "1.x.x || 2.x.x",
3928
+ "clsx": "^2.1.1",
3929
+ "decimal.js-light": "^2.5.1",
3930
+ "es-toolkit": "^1.39.3",
3931
+ "eventemitter3": "^5.0.1",
3932
+ "immer": "^10.1.1",
3933
+ "react-redux": "8.x.x || 9.x.x",
3934
+ "reselect": "5.1.1",
3935
+ "tiny-invariant": "^1.3.3",
3936
+ "use-sync-external-store": "^1.2.2",
3937
+ "victory-vendor": "^37.0.2"
3938
+ },
3939
+ "engines": {
3940
+ "node": ">=18"
3941
+ },
3942
+ "peerDependencies": {
3943
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
3944
+ "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
3945
+ "react-is": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
3946
+ }
3947
+ },
3948
+ "node_modules/redux": {
3949
+ "version": "5.0.1",
3950
+ "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz",
3951
+ "integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==",
3952
+ "license": "MIT"
3953
+ },
3954
+ "node_modules/redux-thunk": {
3955
+ "version": "3.1.0",
3956
+ "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-3.1.0.tgz",
3957
+ "integrity": "sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==",
3958
+ "license": "MIT",
3959
+ "peerDependencies": {
3960
+ "redux": "^5.0.0"
3961
+ }
3962
+ },
3963
+ "node_modules/reselect": {
3964
+ "version": "5.1.1",
3965
+ "resolved": "https://registry.npmjs.org/reselect/-/reselect-5.1.1.tgz",
3966
+ "integrity": "sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==",
3967
+ "license": "MIT"
3968
+ },
3969
  "node_modules/resolve-from": {
3970
  "version": "4.0.0",
3971
  "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
 
4173
  "integrity": "sha512-kH5pKeIIBPQXAOni2AiY/Cu/NKdkFREdpH+TLdM0g6WA7RriCv0kPLgP731ady67MhTAqrVG/4mnEeibVuCJcg==",
4174
  "license": "MIT"
4175
  },
4176
+ "node_modules/tiny-invariant": {
4177
+ "version": "1.3.3",
4178
+ "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz",
4179
+ "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==",
4180
+ "license": "MIT"
4181
+ },
4182
  "node_modules/tinyglobby": {
4183
  "version": "0.2.15",
4184
  "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
 
4355
  "punycode": "^2.1.0"
4356
  }
4357
  },
4358
+ "node_modules/use-sync-external-store": {
4359
+ "version": "1.6.0",
4360
+ "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz",
4361
+ "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==",
4362
+ "license": "MIT",
4363
+ "peerDependencies": {
4364
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
4365
+ }
4366
+ },
4367
+ "node_modules/victory-vendor": {
4368
+ "version": "37.3.6",
4369
+ "resolved": "https://registry.npmjs.org/victory-vendor/-/victory-vendor-37.3.6.tgz",
4370
+ "integrity": "sha512-SbPDPdDBYp+5MJHhBCAyI7wKM3d5ivekigc2Dk2s7pgbZ9wIgIBYGVw4zGHBml/qTFbexrofXW6Gu4noGxrOwQ==",
4371
+ "license": "MIT AND ISC",
4372
+ "dependencies": {
4373
+ "@types/d3-array": "^3.0.3",
4374
+ "@types/d3-ease": "^3.0.0",
4375
+ "@types/d3-interpolate": "^3.0.1",
4376
+ "@types/d3-scale": "^4.0.2",
4377
+ "@types/d3-shape": "^3.1.0",
4378
+ "@types/d3-time": "^3.0.0",
4379
+ "@types/d3-timer": "^3.0.0",
4380
+ "d3-array": "^3.1.6",
4381
+ "d3-ease": "^3.0.1",
4382
+ "d3-interpolate": "^3.0.1",
4383
+ "d3-scale": "^4.0.2",
4384
+ "d3-shape": "^3.1.0",
4385
+ "d3-time": "^3.0.0",
4386
+ "d3-timer": "^3.0.1"
4387
+ }
4388
+ },
4389
  "node_modules/vite": {
4390
  "version": "7.2.2",
4391
  "resolved": "https://registry.npmjs.org/vite/-/vite-7.2.2.tgz",
Frontend/package.json CHANGED
@@ -14,11 +14,13 @@
14
  "@splinetool/runtime": "^1.11.2",
15
  "@tailwindcss/vite": "^4.1.17",
16
  "clsx": "^2.1.1",
 
17
  "framer-motion": "^12.23.24",
18
  "lucide-react": "^0.553.0",
19
  "react": "^19.2.0",
20
  "react-dom": "^19.2.0",
21
  "react-router-dom": "^7.9.5",
 
22
  "tailwind-merge": "^3.4.0",
23
  "tailwindcss": "^4.1.17"
24
  },
 
14
  "@splinetool/runtime": "^1.11.2",
15
  "@tailwindcss/vite": "^4.1.17",
16
  "clsx": "^2.1.1",
17
+ "dayjs": "^1.11.19",
18
  "framer-motion": "^12.23.24",
19
  "lucide-react": "^0.553.0",
20
  "react": "^19.2.0",
21
  "react-dom": "^19.2.0",
22
  "react-router-dom": "^7.9.5",
23
+ "recharts": "^3.4.1",
24
  "tailwind-merge": "^3.4.0",
25
  "tailwindcss": "^4.1.17"
26
  },
Frontend/src/components/dashboard/FeedBackScore.tsx ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React from "react";
2
+
3
+ interface Props {
4
+ confidence: number;
5
+ clarity: number;
6
+ accuracy: number;
7
+ speed: number;
8
+ improvements: string[];
9
+ }
10
+
11
+ const ScoreCard = ({ label, value }: any) => (
12
+ <div className="p-4 text-center bg-gray-100 rounded-xl">
13
+ <p className="text-3xl font-bold text-black">{value}%</p>
14
+ <p className="text-gray-600">{label}</p>
15
+ </div>
16
+ );
17
+
18
+ const FeedbackScore: React.FC<Props> = ({
19
+ confidence,
20
+ clarity,
21
+ accuracy,
22
+ speed,
23
+ improvements,
24
+ }) => {
25
+ return (
26
+ <div className="bg-white p-5 shadow rounded-xl">
27
+ <h3 className="text-xl font-bold mb-3 text-black">AI Feedback Summary</h3>
28
+
29
+ <div className="grid grid-cols-2 md:grid-cols-4 gap-4">
30
+ <ScoreCard label="Confidence" value={confidence} />
31
+ <ScoreCard label="Clarity" value={clarity} />
32
+ <ScoreCard label="Technical Accuracy" value={accuracy} />
33
+ <ScoreCard label="Speed" value={speed} />
34
+ </div>
35
+
36
+ <h4 className="text-lg font-semibold mt-5 text-black">Suggested Improvements</h4>
37
+ <ul className="list-disc pl-5 text-blue-600">
38
+ {improvements.map((item, i) => (
39
+ <li key={i}>{item}</li>
40
+ ))}
41
+ </ul>
42
+ </div>
43
+ );
44
+ };
45
+
46
+ export default FeedbackScore;
Frontend/src/components/dashboard/InterviewPlayback.tsx ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const InterviewPlayback = ({
2
+ audioUrl,
3
+ transcript,
4
+ highlights,
5
+ }: any) => (
6
+ <div className="bg-white p-5 shadow rounded-xl">
7
+ <h3 className="text-xl font-bold mb-4 text-black"> Interview Playback</h3>
8
+
9
+ {audioUrl && (
10
+ <audio controls className="w-full mb-4">
11
+ <source src={audioUrl} type="audio/mp3" />
12
+ </audio>
13
+ )}
14
+
15
+ <h4 className="font-semibold mb-2 text-black"> Transcript</h4>
16
+ <p className="text-gray-700 whitespace-pre-wrap">{transcript}</p>
17
+
18
+ <h4 className="font-semibold mt-4 text-black"> AI Highlights</h4>
19
+ <ul className="list-disc pl-5 text-blue-600">
20
+ {highlights.map((h: string, i: number) => (
21
+ <li key={i}>{h}</li>
22
+ ))}
23
+ </ul>
24
+ </div>
25
+ );
26
+
27
+ export default InterviewPlayback;
Frontend/src/components/dashboard/SkillRadarChart.tsx ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import {
2
+ Radar, RadarChart, PolarGrid, PolarAngleAxis, PolarRadiusAxis, ResponsiveContainer
3
+ } from "recharts";
4
+
5
+ const SkillRadarChart = ({ data }: { data: any[] }) => (
6
+ <div className="bg-white p-5 shadow rounded-xl">
7
+ <h3 className="text-xl font-bold mb-3 text-black">Skill Strength Chart</h3>
8
+
9
+ <div className="w-full h-80">
10
+ <ResponsiveContainer>
11
+ <RadarChart cx="50%" cy="50%" outerRadius="70%" data={data}>
12
+ <PolarGrid />
13
+ <PolarAngleAxis dataKey="skill" />
14
+ <PolarRadiusAxis angle={30} domain={[0, 100]} />
15
+ <Radar
16
+ name="Skill Level"
17
+ dataKey="value"
18
+ stroke="#1170d6"
19
+ fill="#1170d6"
20
+ fillOpacity={0.4}
21
+ />
22
+ </RadarChart>
23
+ </ResponsiveContainer>
24
+ </div>
25
+ </div>
26
+ );
27
+
28
+ export default SkillRadarChart;
Frontend/src/components/dashboard/WeakAreaBanner.tsx ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const WeakAreaBanner = ({ topic }: { topic: string | null }) => {
2
+ if (!topic) return null;
3
+
4
+ return (
5
+ <div className="bg-red-100 p-4 rounded-xl border border-red-300 mt-4">
6
+ <p className="text-red-700 font-semibold">
7
+ ⚠️ You are weak in <strong>{topic}</strong>.
8
+ </p>
9
+ <p className="text-red-600">Start targeted practice today.</p>
10
+ </div>
11
+ );
12
+ };
13
+
14
+ export default WeakAreaBanner;
Frontend/src/components/dashboard/YearlyStreak.tsx ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ interface StreakData {
2
+ date: string;
3
+ count: number;
4
+ weekday: number;
5
+ week: number;
6
+ month: string;
7
+ }
8
+
9
+ const getColor = (count: number) => {
10
+ if (count === 0) return "#2e2e2e";
11
+ if (count === 1) return "#9be9f8";
12
+ if (count === 2) return "#40c4f3";
13
+ if (count === 3) return "#30a1c4";
14
+ return "#216e9c";
15
+ };
16
+ const YearlyStreak = ({ data }: { data: StreakData[] }) => {
17
+ const totalSubmissions = data.reduce((a, b) => a + b.count, 0);
18
+ const activeDays = data.filter((d) => d.count > 0).length;
19
+
20
+ let streak = 0;
21
+ let maxStreak = 0;
22
+ data.forEach((d) => {
23
+ if (d.count > 0) {
24
+ streak++;
25
+ maxStreak = Math.max(maxStreak, streak);
26
+ } else {
27
+ streak = 0;
28
+ }
29
+ });
30
+
31
+ const weeks = data.reduce((acc: any, day) => {
32
+ acc[day.week] = acc[day.week] || [];
33
+ acc[day.week].push(day);
34
+ return acc;
35
+ }, {});
36
+
37
+ return (
38
+ <div className="bg-gray-900 p-6 rounded-xl text-white shadow-xl">
39
+ <div className="flex justify-between mb-4">
40
+ <h3 className="text-xl font-semibold">
41
+ {totalSubmissions} Hour Platform Activities This Year
42
+ </h3>
43
+
44
+ <div className="flex gap-6 text-gray-300">
45
+ <p>Total active days: <span className="text-white">{activeDays}</span></p>
46
+ <p>Max streak: <span className="text-white">{maxStreak}</span></p>
47
+ </div>
48
+ </div>
49
+
50
+ <div className="flex">
51
+ {Object.keys(weeks).map((weekIndex) => (
52
+ <div key={weekIndex} className="flex flex-col mr-1">
53
+ {weeks[weekIndex].map((day: StreakData) => (
54
+ <div
55
+ key={day.date}
56
+ title={`${day.date} — ${day.count} tasks`}
57
+ className="w-4 h-4 rounded-sm mb-1"
58
+ style={{ backgroundColor: getColor(day.count) }}
59
+ />
60
+ ))}
61
+ </div>
62
+ ))}
63
+ </div>
64
+
65
+ <div className="flex mt-3 text-gray-400 text-xs">
66
+ {Object.keys(weeks).map((weekIndex) => {
67
+ const firstDay = weeks[weekIndex][0];
68
+ const showLabel = firstDay.date.endsWith("01");
69
+ return (
70
+ <div key={weekIndex} className="w-4 mx-[2px]">
71
+ {showLabel && <span>{firstDay.month}</span>}
72
+ </div>
73
+ );
74
+ })}
75
+ </div>
76
+ </div>
77
+ );
78
+ };
79
+
80
+ export default YearlyStreak;
Frontend/src/components/ui/card.tsx DELETED
@@ -1,81 +0,0 @@
1
- import * as React from "react"
2
- import { cn } from "../../lib/utils"
3
-
4
- // 1. Corrected forwardRef syntax: <RefType, PropsType>(...)
5
- // 2. Used modern typing: React.ElementRef<"tag"> and React.ComponentPropsWithoutRef<"tag">
6
-
7
- const Card = React.forwardRef<
8
- React.ElementRef<"div">,
9
- React.ComponentPropsWithoutRef<"div">
10
- >(({ className, ...props }, ref) => (
11
- <div
12
- ref={ref}
13
- className={cn(
14
- "rounded-lg border bg-card text-card-foreground shadow-sm",
15
- className,
16
- )}
17
- {...props}
18
- />
19
- ))
20
- Card.displayName = "Card"
21
-
22
- const CardHeader = React.forwardRef<
23
- React.ElementRef<"div">,
24
- React.ComponentPropsWithoutRef<"div">
25
- >(({ className, ...props }, ref) => (
26
- <div
27
- ref={ref}
28
- className={cn("flex flex-col space-y-1.5 p-6", className)}
29
- {...props}
30
- />
31
- ))
32
- CardHeader.displayName = "CardHeader"
33
-
34
- const CardTitle = React.forwardRef<
35
- React.ElementRef<"h3">, // Corrected to h3 to match the element type
36
- React.ComponentPropsWithoutRef<"h3">
37
- >(({ className, ...props }, ref) => (
38
- <h3
39
- ref={ref}
40
- className={cn(
41
- "text-2xl font-semibold leading-none tracking-tight",
42
- className,
43
- )}
44
- {...props}
45
- />
46
- ))
47
- CardTitle.displayName = "CardTitle"
48
-
49
- const CardDescription = React.forwardRef<
50
- React.ElementRef<"p">,
51
- React.ComponentPropsWithoutRef<"p">
52
- >(({ className, ...props }, ref) => (
53
- <p
54
- ref={ref}
55
- className={cn("text-sm text-muted-foreground", className)}
56
- {...props}
57
- />
58
- ))
59
- CardDescription.displayName = "CardDescription"
60
-
61
- const CardContent = React.forwardRef<
62
- React.ElementRef<"div">,
63
- React.ComponentPropsWithoutRef<"div">
64
- >(({ className, ...props }, ref) => (
65
- <div ref={ref} className={cn("p-6 pt-0", className)} {...props} />
66
- ))
67
- CardContent.displayName = "CardContent"
68
-
69
- const CardFooter = React.forwardRef<
70
- React.ElementRef<"div">,
71
- React.ComponentPropsWithoutRef<"div">
72
- >(({ className, ...props }, ref) => (
73
- <div
74
- ref={ref}
75
- className={cn("flex items-center p-6 pt-0", className)}
76
- {...props}
77
- />
78
- ))
79
- CardFooter.displayName = "CardFooter"
80
-
81
- export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Frontend/src/pages/dashboard.tsx CHANGED
@@ -1,14 +1,112 @@
1
- import React from "react";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
 
3
- const Dashboard: React.FC = () => {
4
  return (
5
- <div className="text-gray-800">
6
- <h2 className="text-3xl font-bold mb-4">Welcome to InterviewAI Dashboard</h2>
7
- <p className="text-gray-600">
8
- Manage your AI interview sessions, quizzes, and notes all in one place.
9
- </p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  </div>
11
  );
12
  };
13
 
14
- export default Dashboard;
 
1
+ import YearlyStreak from "../components/dashboard/YearlyStreak";
2
+ import FeedbackScore from "../components/dashboard/FeedBackScore";
3
+ import SkillRadarChart from "../components/dashboard/SkillRadarChart";
4
+ import WeakAreaBanner from "../components/dashboard/WeakAreaBanner";
5
+ import InterviewPlayback from "../components/dashboard/InterviewPlayback";
6
+ import { generateYearlyStreakData } from "../utils/generateYearlyStreakData";
7
+
8
+ const Dashboard = () => {
9
+ const streakData = generateYearlyStreakData();
10
+
11
+ const radarData = [
12
+ { skill: "DSA", value: 70 },
13
+ { skill: "System Design", value: 60 },
14
+ { skill: "Communication", value: 85 },
15
+ { skill: "Problem Solving", value: 75 },
16
+ { skill: "Accuracy", value: 68 },
17
+ { skill: "Time Mgmt", value: 80 },
18
+ ];
19
+
20
+ const weakTopic = "Dynamic Programming";
21
 
 
22
  return (
23
+ // PRIMARY CHANGE: Background Gradient inspired by landing page
24
+ // Using a custom CSS class for a more complex gradient if needed, or approximating with Tailwind.
25
+ // For now, let's use a subtle linear gradient that implies the dark blue-black.
26
+ <div className="px-6 py-8 space-y-10 min-h-screen text-gray-100 bg-linear-to-br from-[#0a0e1b] via-[#100d27] to-[#0a0e1b] font-sans">
27
+ {/* Font sans is a good default for modern look */}
28
+
29
+ {/* ----------- HEADER SECTION (Updated for new theme) ----------- */}
30
+ <div className="flex flex-col md:flex-row md:items-center justify-between mb-4">
31
+ <h1 className="text-3xl lg:text-4xl font-extrabold text-gray-50 tracking-tight">
32
+ 👋 Welcome back, <span className="text-blue-400">Prakhar</span>
33
+ </h1>
34
+
35
+ <div className="flex items-center space-x-3 mt-4 md:mt-0">
36
+ {/* PRIMARY BUTTON: Vibrant Purple Theme Color, matching "Start Free Trial" */}
37
+ <button className="px-6 py-2 bg-gradient-to-r from-blue-600 to-blue-800 text-white rounded-lg shadow-lg shadow-purple-500/30 hover:from-blue-500 hover:to-blue-700 transition-all duration-300 ease-in-out font-semibold">
38
+ Start Interview
39
+ </button>
40
+ </div>
41
+ </div>
42
+
43
+ {/* ----------- GRID MAIN LAYOUT (2 COLUMNS for top content) ----------- */}
44
+ <div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
45
+
46
+ {/* LEFT PANEL (Feedback Score) */}
47
+ <div className="space-y-6 col-span-1">
48
+ {/* CARD BACKGROUND CHANGE: Dark Card Color, subtle border/shadow */}
49
+ <div className="bg-gradient-to-br from-[#1a202c] to-[#2d3748] rounded-xl shadow-lg p-6 border border-gray-700/50 h-full">
50
+ <h2 className="text-xl font-bold mb-4 text-gray-50">AI Feedback Score</h2>
51
+ <FeedbackScore
52
+ confidence={78}
53
+ clarity={82}
54
+ accuracy={70}
55
+ speed={65}
56
+ improvements={[
57
+ "Improve explanation clarity",
58
+ "Practice more DP problems",
59
+ "Reduce filler words in answers",
60
+ ]}
61
+ />
62
+ </div>
63
+ </div>
64
+
65
+ {/* RIGHT PANEL (Skill Chart) */}
66
+ <div className="space-y-6 col-span-1">
67
+ {/* CARD BACKGROUND CHANGE: Dark Card Color, subtle border/shadow */}
68
+ <div className="bg-gradient-to-br from-[#1a202c] to-[#2d3748] rounded-xl shadow-lg p-6 border border-gray-700/50 h-full">
69
+ <h2 className="text-xl font-bold mb-4 text-gray-50">Skill Strength Chart</h2>
70
+ <SkillRadarChart data={radarData} />
71
+ </div>
72
+ </div>
73
+ </div>
74
+
75
+ {/* ----------- MIDDLE ROW: INTERVIEW PLAYBACK (LEFT) AND WEAK AREA (RIGHT) ----------- */}
76
+ <div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
77
+
78
+ {/* INTERVIEW PLAYBACK (2/3 width on large screens, LEFT) */}
79
+ {/* CARD BACKGROUND CHANGE: Dark Card Color, subtle border/shadow */}
80
+ <div className="bg-gradient-to-br from-[#1a202c] to-[#2d3748] rounded-xl shadow-lg p-6 border border-gray-700/50 lg:col-span-2">
81
+ <h2 className="text-xl font-bold mb-4 text-gray-50">Interview Playback AI Feedback</h2>
82
+ <InterviewPlayback
83
+ audioUrl="https://example.com/audio.mp3"
84
+ transcript={`Interviewer: Explain polymorphism.\nYou: Polymorphism means...`}
85
+ highlights={[
86
+ "Answer lacked real-world example",
87
+ "Need more clarity in describing LLD concepts",
88
+ "Example Interview Playback",
89
+ ]}
90
+ />
91
+ </div>
92
+
93
+ {/* WEAK AREA (1/3 width on large screens, RIGHT) */}
94
+ {/* CARD BACKGROUND CHANGE: Dark Card Color, subtle border/shadow */}
95
+ <div className="bg-gradient-to-br from-[#1a202c] to-[#2d3748] rounded-xl shadow-lg p-5 border border-gray-700/50 col-span-1 flex-col items-center justify-center">
96
+ {/* WeakAreaBanner will need internal styling adjustments for its alert nature */}
97
+ <h2 className="text-xl font-bold mb-4 text-gray-50">WeakAreaBanner</h2>
98
+ <WeakAreaBanner topic={weakTopic} />
99
+ </div>
100
+ </div>
101
+
102
+ {/* ----------- BOTTOM ROW: YEARLY STREAK (FULL WIDTH) ----------- */}
103
+ {/* CARD BACKGROUND CHANGE: Dark Card Color, subtle border/shadow */}
104
+ <div className="bg-gradient-to-br from-[#1a202c] to-[#2d3748] rounded-xl shadow-lg p-6 border border-gray-700/50">
105
+ <h2 className="text-xl font-bold mb-3 text-gray-50">Yearly Streak</h2>
106
+ <YearlyStreak data={streakData} />
107
+ </div>
108
  </div>
109
  );
110
  };
111
 
112
+ export default Dashboard;
Frontend/src/pages/home.tsx CHANGED
@@ -200,7 +200,7 @@ const AIInterviewPlatform: React.FC<AIInterviewPlatformProps> = ({ onLogin }) =>
200
  </AuthModal>
201
 
202
  {/* Hero Section */}
203
- <section ref={heroRef} id="home" className="min-h-[calc(100vh-68px)] flex items-center pt- pb-20 px-4 sm:px-6 lg:px-8 relative overflow-hidden bg-black">
204
  {/* Spotlight applied directly to the container as per the demo structure */}
205
  <Spotlight parentRef={heroRef} color="#4b9fff" className="mix-blend-screen" />
206
  <div className="max-w-7xl mx-auto w-full relative z-10">
 
200
  </AuthModal>
201
 
202
  {/* Hero Section */}
203
+ <section ref={heroRef} id="home" className="min-h-[calc(100vh-68px)] flex items-center pt-20 pb-20 px-4 sm:px-6 lg:px-8 relative overflow-hidden bg-black">
204
  {/* Spotlight applied directly to the container as per the demo structure */}
205
  <Spotlight parentRef={heroRef} color="#4b9fff" className="mix-blend-screen" />
206
  <div className="max-w-7xl mx-auto w-full relative z-10">
Frontend/src/pages/quize.tsx CHANGED
@@ -1,121 +1,125 @@
1
  import React from "react";
2
- import { FileText, BrainCircuit, FileSpreadsheet, Mic, Code2, Edit3, ListChecks } from "lucide-react";
3
 
 
4
  const ResumeGeneratedQuize: React.FC = () => {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
  return (
6
  <div className="min-h-screen bg-black text-white py-20 px-6 lg:px-12">
7
 
8
  {/* Page Title */}
9
- <h1 className="text-4xl font-bold mb-10 text-center">
10
  Smart AI-Powered Quiz Generator
11
  </h1>
12
 
13
- {/* ===== QUIZ SOURCES ===== */}
14
- <div className="grid grid-cols-1 md:grid-cols-3 gap-8 mb-16">
15
-
16
- {/* AI Generated Quiz */}
17
- <div className="p-6 bg-slate-900/60 rounded-2xl shadow-xl border border-slate-800 hover:bg-slate-800/70 transition">
18
- <div className="flex items-center gap-3 mb-4">
19
- <BrainCircuit className="w-8 h-8 text-blue-400" />
20
- <h2 className="text-2xl font-bold">AI Generated Quiz</h2>
 
 
 
 
 
 
 
 
21
  </div>
22
- <p className="text-gray-300">
23
- Create intelligent quizzes using AI-generated questions tailored to your learning needs.
24
- </p>
25
  </div>
26
 
27
- {/* Resume Based Quiz */}
28
- <div className="p-6 bg-slate-900/60 rounded-2xl shadow-xl border border-slate-800 hover:bg-slate-800/70 transition">
29
- <div className="flex items-center gap-3 mb-4">
30
- <FileSpreadsheet className="w-8 h-8 text-blue-400" />
31
- <h2 className="text-2xl font-bold">Resume-Based Quiz</h2>
32
- </div>
33
- <p className="text-gray-300">
34
- Upload your resume and get customized quizzes based on your skills & experiences.
35
- </p>
36
- </div>
37
 
38
- {/* PDF Based Quiz */}
39
- <div className="p-6 bg-slate-900/60 rounded-2xl shadow-xl border border-slate-800 hover:bg-slate-800/70 transition">
40
- <div className="flex items-center gap-3 mb-4">
41
- <FileText className="w-8 h-8 text-blue-400" />
42
- <h2 className="text-2xl font-bold">PDF-Based Quiz</h2>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
  </div>
44
- <p className="text-gray-300">
45
- Generate quizzes instantly from uploaded PDF documents. Perfect for study notes.
46
- </p>
47
  </div>
48
 
49
  </div>
50
 
51
- {/* ===== QUIZ TYPES ===== */}
52
- <h2 className="text-3xl font-bold mb-8 text-center">Quiz Types</h2>
53
-
54
- <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-8">
55
-
56
- {/* MCQ Quiz */}
57
- <QuizTypeCard
58
- icon={<ListChecks className="w-10 h-10 text-purple-400" />}
59
- title="MCQ Quiz"
60
- desc="Multiple choice questions auto-generated by AI."
61
- />
62
-
63
- {/* Coding Quiz */}
64
- <QuizTypeCard
65
- icon={<Code2 className="w-10 h-10 text-green-400" />}
66
- title="Coding Quiz"
67
- desc="AI generates code problems based on your skills."
68
- />
69
-
70
- {/* Voice Based Quiz */}
71
- <QuizTypeCard
72
- icon={<Mic className="w-10 h-10 text-red-400" />}
73
- title="Voice-Based Quiz"
74
- desc="Answer questions via voice great for interviews."
75
- />
76
-
77
- {/* Writing Based Quiz */}
78
- <QuizTypeCard
79
- icon={<Edit3 className="w-10 h-10 text-blue-300" />}
80
- title="Writing Quiz"
81
- desc="Subjective, long-form answers graded by AI."
82
- />
83
 
84
  </div>
85
  </div>
86
  );
87
  };
88
 
89
- export default ResumeGeneratedQuize;
90
-
91
-
92
- /* ===== Reusable Quiz Card Component ===== */
93
-
94
- const QuizTypeCard = ({
95
- icon,
96
- title,
97
- desc,
98
- }: {
99
- icon: React.ReactNode;
100
- title: string;
101
- desc: string;
102
- }) => {
103
- return (
104
- <div className="p-6 bg-slate-900/60 rounded-2xl shadow-xl border border-slate-800 hover:bg-slate-800/70 transition flex flex-col items-start gap-3">
105
- {icon}
106
- <h3 className="text-xl font-semibold">{title}</h3>
107
- <p className="text-gray-400">{desc}</p>
108
-
109
- <button
110
- className="
111
- mt-4 px-4 py-2 rounded-lg
112
- bg-gradient-to-r from-blue-600 to-purple-600
113
- hover:from-blue-700 hover:to-purple-700
114
- font-medium transition shadow-lg
115
- "
116
- >
117
- Start Quiz
118
- </button>
119
- </div>
120
- );
121
- };
 
1
  import React from "react";
2
+ import { FileText, FileSpreadsheet, Code2, ListChecks, UploadCloud, Type } from "lucide-react";
3
 
4
+ // The structure of this component is heavily modified to meet the new layout requirements.
5
  const ResumeGeneratedQuize: React.FC = () => {
6
+
7
+ // Consistent purple button style
8
+ const buttonClass = "w-full py-3 rounded-lg bg-gradient-to-r from-purple-500 to-purple-700 hover:from-purple-400 hover:to-purple-600 font-medium transition shadow-lg shadow-purple-500/30 text-white mt-4";
9
+
10
+ const OutputTypeOption = ({ icon, title, desc }: { icon: React.ReactNode; title: string; desc: string }) => (
11
+ // These cards inherently take full width of their parent container (which is now the right column)
12
+ <div className="p-4 bg-slate-900/50 rounded-xl border border-slate-700 hover:bg-slate-800/60 transition cursor-pointer">
13
+ <div className="flex items-center gap-3 mb-2">
14
+ {icon}
15
+ <h4 className="text-xl font-semibold text-gray-50">{title}</h4>
16
+ </div>
17
+ <p className="text-gray-400 text-sm">{desc}</p>
18
+ </div>
19
+ );
20
+
21
+ const SourceCard = ({ icon, title, desc, actionText }: { icon: React.ReactNode; title: string; desc: string; actionText: string }) => (
22
+ <div className="p-6 bg-slate-900/60 rounded-2xl shadow-xl border border-slate-700 hover:bg-slate-800/70 transition flex flex-col h-full">
23
+ <div className="flex items-start gap-4 mb-4">
24
+ {icon}
25
+ <div>
26
+ <h2 className="text-2xl font-bold">{title}</h2>
27
+ <p className="text-gray-400 mt-1 text-sm">{desc}</p>
28
+ </div>
29
+ </div>
30
+ {/* The SourceCard button width is intentionally set to w-fit px-6 to be narrower */}
31
+ <button className={buttonClass.replace('w-full', 'w-fit px-6')} >
32
+ {actionText}
33
+ </button>
34
+ </div>
35
+ );
36
+
37
  return (
38
  <div className="min-h-screen bg-black text-white py-20 px-6 lg:px-12">
39
 
40
  {/* Page Title */}
41
+ <h1 className="text-4xl font-bold mb-16 text-center">
42
  Smart AI-Powered Quiz Generator
43
  </h1>
44
 
45
+ {/* ===== MAIN TWO-COLUMN LAYOUT (Source Selection vs. Configuration) ===== */}
46
+ <div className="grid grid-cols-1 lg:grid-cols-2 gap-12">
47
+
48
+ {/* --- LEFT SIDE: INPUT SOURCE SELECTION --- */}
49
+ <div>
50
+ <h3 className="text-3xl font-bold mb-6 text-gray-100 border-b border-purple-700 pb-2">
51
+ 1. Select Quiz Source
52
+ </h3>
53
+ <div className="space-y-8">
54
+ {/* Consolidated Resume/Note PDF Upload Card */}
55
+ <SourceCard
56
+ icon={<FileSpreadsheet className="w-8 h-8 text-cyan-400" />}
57
+ title="Resume/Note PDF Upload"
58
+ desc="Generate quizzes based on skills and experience listed in your resume file."
59
+ actionText="Upload"
60
+ />
61
  </div>
 
 
 
62
  </div>
63
 
 
 
 
 
 
 
 
 
 
 
64
 
65
+ {/* --- RIGHT SIDE: PROMPT & OUTPUT CONFIGURATION (The full width section) --- */}
66
+ <div className="lg:sticky lg:top-8 self-start">
67
+ <h3 className="text-3xl font-bold mb-6 text-gray-100 border-b border-purple-700 pb-2">
68
+ 2. Configure & Generate
69
+ </h3>
70
+
71
+ {/* Prompt/Text Area Section */}
72
+ <div className="bg-slate-900/60 rounded-2xl shadow-2xl p-6 border border-slate-800 mb-8">
73
+ <label htmlFor="prompt-area" className="text-lg font-semibold block mb-3 text-gray-200">
74
+ Custom Prompt/Instructions (Optional)
75
+ </label>
76
+ <textarea
77
+ id="prompt-area"
78
+ rows={4}
79
+ placeholder="e.g., 'Focus only on Python and OOP concepts' or 'Generate a quiz on the content uploaded in step 1'"
80
+ className="w-full p-3 rounded-lg bg-black/40 border border-slate-700 text-gray-100 placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-purple-600 transition"
81
+ ></textarea>
82
+ <p className="text-gray-500 text-sm mt-2">
83
+ This prompt refines the quiz generation based on the selected source.
84
+ </p>
85
  </div>
86
+
87
+ {/* Output Type Section - NOW CORRECTLY PLACED INSIDE THE RIGHT COLUMN */}
 
88
  </div>
89
 
90
  </div>
91
 
92
+ <div className="lg:sticky lg:top-8 self-start">
93
+ <h4 className="text-2xl font-semibold mb-4 text-gray-200">
94
+ Choose Output Type:
95
+ </h4>
96
+
97
+ {/* NEW: Use grid-cols-2 and gap-4 to place the options side-by-side */}
98
+ <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
99
+
100
+ {/* MCQ Quiz Option - takes full width of its column */}
101
+ <OutputTypeOption
102
+ icon={<ListChecks className="w-6 h-6 text-purple-400" />}
103
+ title="Multiple Choice Quiz (MCQ)"
104
+ desc="Ideal for quick assessment of knowledge and comprehension."
105
+ />
106
+
107
+ {/* Coding Quiz Option - takes full width of its column */}
108
+ <OutputTypeOption
109
+ icon={<Code2 className="w-6 h-6 text-green-400" />}
110
+ title="Coding Challenge Quiz"
111
+ desc="Generates problems requiring code snippets or full functions for evaluation."
112
+ />
113
+ </div>
114
+
115
+ {/* Main Generation Button - Full width (w-full is in buttonClass) */}
116
+ <button className={buttonClass + ' text-xl mt-8'}>
117
+ Generate Quiz Now
118
+ </button>
 
 
 
 
 
119
 
120
  </div>
121
  </div>
122
  );
123
  };
124
 
125
+ export default ResumeGeneratedQuize;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Frontend/src/utils/generateYearlyStreakData.ts ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import dayjs from "dayjs";
2
+
3
+ export const generateYearlyStreakData = () => {
4
+ const today = dayjs();
5
+ const days = [];
6
+
7
+ for (let i = 0; i < 365; i++) {
8
+ const date = today.subtract(i, "day");
9
+
10
+ days.push({
11
+ date: date.format("YYYY-MM-DD"),
12
+ count: Math.floor(Math.random() * 4), // 0–3 activity
13
+ weekday: date.day(),
14
+ week: Math.floor(i / 7),
15
+ month: date.format("MMM"),
16
+ });
17
+ }
18
+
19
+ return days.reverse();
20
+ };