Prakhar Singh commited on
Commit
90f0c0b
·
1 Parent(s): c9abf3f

endpoint is running

Browse files
Frontend/package-lock.json CHANGED
@@ -12,6 +12,7 @@
12
  "@splinetool/react-spline": "^4.1.0",
13
  "@splinetool/runtime": "^1.11.2",
14
  "@tailwindcss/vite": "^4.1.17",
 
15
  "clsx": "^2.1.1",
16
  "dayjs": "^1.11.19",
17
  "framer-motion": "^12.23.24",
@@ -2159,6 +2160,23 @@
2159
  "dev": true,
2160
  "license": "Python-2.0"
2161
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2162
  "node_modules/balanced-match": {
2163
  "version": "1.0.2",
2164
  "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
@@ -2240,6 +2258,19 @@
2240
  "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
2241
  }
2242
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
2243
  "node_modules/callsites": {
2244
  "version": "3.1.0",
2245
  "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
@@ -2317,6 +2348,18 @@
2317
  "dev": true,
2318
  "license": "MIT"
2319
  },
 
 
 
 
 
 
 
 
 
 
 
 
2320
  "node_modules/concat-map": {
2321
  "version": "0.0.1",
2322
  "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@@ -2520,6 +2563,15 @@
2520
  "dev": true,
2521
  "license": "MIT"
2522
  },
 
 
 
 
 
 
 
 
 
2523
  "node_modules/detect-libc": {
2524
  "version": "2.1.2",
2525
  "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
@@ -2529,6 +2581,20 @@
2529
  "node": ">=8"
2530
  }
2531
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2532
  "node_modules/electron-to-chromium": {
2533
  "version": "1.5.249",
2534
  "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.249.tgz",
@@ -2549,6 +2615,51 @@
2549
  "node": ">=10.13.0"
2550
  }
2551
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2552
  "node_modules/es-toolkit": {
2553
  "version": "1.41.0",
2554
  "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.41.0.tgz",
@@ -2931,6 +3042,42 @@
2931
  "dev": true,
2932
  "license": "ISC"
2933
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2934
  "node_modules/framer-motion": {
2935
  "version": "12.23.24",
2936
  "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.23.24.tgz",
@@ -2972,6 +3119,15 @@
2972
  "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
2973
  }
2974
  },
 
 
 
 
 
 
 
 
 
2975
  "node_modules/gensync": {
2976
  "version": "1.0.0-beta.2",
2977
  "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
@@ -2982,6 +3138,43 @@
2982
  "node": ">=6.9.0"
2983
  }
2984
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2985
  "node_modules/glob-parent": {
2986
  "version": "6.0.2",
2987
  "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
@@ -3008,6 +3201,18 @@
3008
  "url": "https://github.com/sponsors/sindresorhus"
3009
  }
3010
  },
 
 
 
 
 
 
 
 
 
 
 
 
3011
  "node_modules/graceful-fs": {
3012
  "version": "4.2.11",
3013
  "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
@@ -3031,6 +3236,45 @@
3031
  "node": ">=8"
3032
  }
3033
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3034
  "node_modules/ignore": {
3035
  "version": "5.3.2",
3036
  "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
@@ -3533,6 +3777,15 @@
3533
  "@jridgewell/sourcemap-codec": "^1.5.5"
3534
  }
3535
  },
 
 
 
 
 
 
 
 
 
3536
  "node_modules/merge2": {
3537
  "version": "1.4.1",
3538
  "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
@@ -3557,6 +3810,27 @@
3557
  "node": ">=8.6"
3558
  }
3559
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3560
  "node_modules/minimatch": {
3561
  "version": "3.1.2",
3562
  "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
@@ -3776,6 +4050,12 @@
3776
  "node": ">= 0.8.0"
3777
  }
3778
  },
 
 
 
 
 
 
3779
  "node_modules/punycode": {
3780
  "version": "2.3.1",
3781
  "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
 
12
  "@splinetool/react-spline": "^4.1.0",
13
  "@splinetool/runtime": "^1.11.2",
14
  "@tailwindcss/vite": "^4.1.17",
15
+ "axios": "^1.13.2",
16
  "clsx": "^2.1.1",
17
  "dayjs": "^1.11.19",
18
  "framer-motion": "^12.23.24",
 
2160
  "dev": true,
2161
  "license": "Python-2.0"
2162
  },
2163
+ "node_modules/asynckit": {
2164
+ "version": "0.4.0",
2165
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
2166
+ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
2167
+ "license": "MIT"
2168
+ },
2169
+ "node_modules/axios": {
2170
+ "version": "1.13.2",
2171
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.2.tgz",
2172
+ "integrity": "sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==",
2173
+ "license": "MIT",
2174
+ "dependencies": {
2175
+ "follow-redirects": "^1.15.6",
2176
+ "form-data": "^4.0.4",
2177
+ "proxy-from-env": "^1.1.0"
2178
+ }
2179
+ },
2180
  "node_modules/balanced-match": {
2181
  "version": "1.0.2",
2182
  "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
 
2258
  "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
2259
  }
2260
  },
2261
+ "node_modules/call-bind-apply-helpers": {
2262
+ "version": "1.0.2",
2263
+ "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
2264
+ "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
2265
+ "license": "MIT",
2266
+ "dependencies": {
2267
+ "es-errors": "^1.3.0",
2268
+ "function-bind": "^1.1.2"
2269
+ },
2270
+ "engines": {
2271
+ "node": ">= 0.4"
2272
+ }
2273
+ },
2274
  "node_modules/callsites": {
2275
  "version": "3.1.0",
2276
  "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
 
2348
  "dev": true,
2349
  "license": "MIT"
2350
  },
2351
+ "node_modules/combined-stream": {
2352
+ "version": "1.0.8",
2353
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
2354
+ "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
2355
+ "license": "MIT",
2356
+ "dependencies": {
2357
+ "delayed-stream": "~1.0.0"
2358
+ },
2359
+ "engines": {
2360
+ "node": ">= 0.8"
2361
+ }
2362
+ },
2363
  "node_modules/concat-map": {
2364
  "version": "0.0.1",
2365
  "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
 
2563
  "dev": true,
2564
  "license": "MIT"
2565
  },
2566
+ "node_modules/delayed-stream": {
2567
+ "version": "1.0.0",
2568
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
2569
+ "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
2570
+ "license": "MIT",
2571
+ "engines": {
2572
+ "node": ">=0.4.0"
2573
+ }
2574
+ },
2575
  "node_modules/detect-libc": {
2576
  "version": "2.1.2",
2577
  "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
 
2581
  "node": ">=8"
2582
  }
2583
  },
2584
+ "node_modules/dunder-proto": {
2585
+ "version": "1.0.1",
2586
+ "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
2587
+ "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
2588
+ "license": "MIT",
2589
+ "dependencies": {
2590
+ "call-bind-apply-helpers": "^1.0.1",
2591
+ "es-errors": "^1.3.0",
2592
+ "gopd": "^1.2.0"
2593
+ },
2594
+ "engines": {
2595
+ "node": ">= 0.4"
2596
+ }
2597
+ },
2598
  "node_modules/electron-to-chromium": {
2599
  "version": "1.5.249",
2600
  "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.249.tgz",
 
2615
  "node": ">=10.13.0"
2616
  }
2617
  },
2618
+ "node_modules/es-define-property": {
2619
+ "version": "1.0.1",
2620
+ "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
2621
+ "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
2622
+ "license": "MIT",
2623
+ "engines": {
2624
+ "node": ">= 0.4"
2625
+ }
2626
+ },
2627
+ "node_modules/es-errors": {
2628
+ "version": "1.3.0",
2629
+ "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
2630
+ "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
2631
+ "license": "MIT",
2632
+ "engines": {
2633
+ "node": ">= 0.4"
2634
+ }
2635
+ },
2636
+ "node_modules/es-object-atoms": {
2637
+ "version": "1.1.1",
2638
+ "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
2639
+ "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
2640
+ "license": "MIT",
2641
+ "dependencies": {
2642
+ "es-errors": "^1.3.0"
2643
+ },
2644
+ "engines": {
2645
+ "node": ">= 0.4"
2646
+ }
2647
+ },
2648
+ "node_modules/es-set-tostringtag": {
2649
+ "version": "2.1.0",
2650
+ "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
2651
+ "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
2652
+ "license": "MIT",
2653
+ "dependencies": {
2654
+ "es-errors": "^1.3.0",
2655
+ "get-intrinsic": "^1.2.6",
2656
+ "has-tostringtag": "^1.0.2",
2657
+ "hasown": "^2.0.2"
2658
+ },
2659
+ "engines": {
2660
+ "node": ">= 0.4"
2661
+ }
2662
+ },
2663
  "node_modules/es-toolkit": {
2664
  "version": "1.41.0",
2665
  "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.41.0.tgz",
 
3042
  "dev": true,
3043
  "license": "ISC"
3044
  },
3045
+ "node_modules/follow-redirects": {
3046
+ "version": "1.15.11",
3047
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz",
3048
+ "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==",
3049
+ "funding": [
3050
+ {
3051
+ "type": "individual",
3052
+ "url": "https://github.com/sponsors/RubenVerborgh"
3053
+ }
3054
+ ],
3055
+ "license": "MIT",
3056
+ "engines": {
3057
+ "node": ">=4.0"
3058
+ },
3059
+ "peerDependenciesMeta": {
3060
+ "debug": {
3061
+ "optional": true
3062
+ }
3063
+ }
3064
+ },
3065
+ "node_modules/form-data": {
3066
+ "version": "4.0.5",
3067
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz",
3068
+ "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==",
3069
+ "license": "MIT",
3070
+ "dependencies": {
3071
+ "asynckit": "^0.4.0",
3072
+ "combined-stream": "^1.0.8",
3073
+ "es-set-tostringtag": "^2.1.0",
3074
+ "hasown": "^2.0.2",
3075
+ "mime-types": "^2.1.12"
3076
+ },
3077
+ "engines": {
3078
+ "node": ">= 6"
3079
+ }
3080
+ },
3081
  "node_modules/framer-motion": {
3082
  "version": "12.23.24",
3083
  "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.23.24.tgz",
 
3119
  "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
3120
  }
3121
  },
3122
+ "node_modules/function-bind": {
3123
+ "version": "1.1.2",
3124
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
3125
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
3126
+ "license": "MIT",
3127
+ "funding": {
3128
+ "url": "https://github.com/sponsors/ljharb"
3129
+ }
3130
+ },
3131
  "node_modules/gensync": {
3132
  "version": "1.0.0-beta.2",
3133
  "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
 
3138
  "node": ">=6.9.0"
3139
  }
3140
  },
3141
+ "node_modules/get-intrinsic": {
3142
+ "version": "1.3.0",
3143
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
3144
+ "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
3145
+ "license": "MIT",
3146
+ "dependencies": {
3147
+ "call-bind-apply-helpers": "^1.0.2",
3148
+ "es-define-property": "^1.0.1",
3149
+ "es-errors": "^1.3.0",
3150
+ "es-object-atoms": "^1.1.1",
3151
+ "function-bind": "^1.1.2",
3152
+ "get-proto": "^1.0.1",
3153
+ "gopd": "^1.2.0",
3154
+ "has-symbols": "^1.1.0",
3155
+ "hasown": "^2.0.2",
3156
+ "math-intrinsics": "^1.1.0"
3157
+ },
3158
+ "engines": {
3159
+ "node": ">= 0.4"
3160
+ },
3161
+ "funding": {
3162
+ "url": "https://github.com/sponsors/ljharb"
3163
+ }
3164
+ },
3165
+ "node_modules/get-proto": {
3166
+ "version": "1.0.1",
3167
+ "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
3168
+ "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
3169
+ "license": "MIT",
3170
+ "dependencies": {
3171
+ "dunder-proto": "^1.0.1",
3172
+ "es-object-atoms": "^1.0.0"
3173
+ },
3174
+ "engines": {
3175
+ "node": ">= 0.4"
3176
+ }
3177
+ },
3178
  "node_modules/glob-parent": {
3179
  "version": "6.0.2",
3180
  "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
 
3201
  "url": "https://github.com/sponsors/sindresorhus"
3202
  }
3203
  },
3204
+ "node_modules/gopd": {
3205
+ "version": "1.2.0",
3206
+ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
3207
+ "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
3208
+ "license": "MIT",
3209
+ "engines": {
3210
+ "node": ">= 0.4"
3211
+ },
3212
+ "funding": {
3213
+ "url": "https://github.com/sponsors/ljharb"
3214
+ }
3215
+ },
3216
  "node_modules/graceful-fs": {
3217
  "version": "4.2.11",
3218
  "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
 
3236
  "node": ">=8"
3237
  }
3238
  },
3239
+ "node_modules/has-symbols": {
3240
+ "version": "1.1.0",
3241
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
3242
+ "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
3243
+ "license": "MIT",
3244
+ "engines": {
3245
+ "node": ">= 0.4"
3246
+ },
3247
+ "funding": {
3248
+ "url": "https://github.com/sponsors/ljharb"
3249
+ }
3250
+ },
3251
+ "node_modules/has-tostringtag": {
3252
+ "version": "1.0.2",
3253
+ "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
3254
+ "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
3255
+ "license": "MIT",
3256
+ "dependencies": {
3257
+ "has-symbols": "^1.0.3"
3258
+ },
3259
+ "engines": {
3260
+ "node": ">= 0.4"
3261
+ },
3262
+ "funding": {
3263
+ "url": "https://github.com/sponsors/ljharb"
3264
+ }
3265
+ },
3266
+ "node_modules/hasown": {
3267
+ "version": "2.0.2",
3268
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
3269
+ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
3270
+ "license": "MIT",
3271
+ "dependencies": {
3272
+ "function-bind": "^1.1.2"
3273
+ },
3274
+ "engines": {
3275
+ "node": ">= 0.4"
3276
+ }
3277
+ },
3278
  "node_modules/ignore": {
3279
  "version": "5.3.2",
3280
  "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
 
3777
  "@jridgewell/sourcemap-codec": "^1.5.5"
3778
  }
3779
  },
3780
+ "node_modules/math-intrinsics": {
3781
+ "version": "1.1.0",
3782
+ "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
3783
+ "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
3784
+ "license": "MIT",
3785
+ "engines": {
3786
+ "node": ">= 0.4"
3787
+ }
3788
+ },
3789
  "node_modules/merge2": {
3790
  "version": "1.4.1",
3791
  "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
 
3810
  "node": ">=8.6"
3811
  }
3812
  },
3813
+ "node_modules/mime-db": {
3814
+ "version": "1.52.0",
3815
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
3816
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
3817
+ "license": "MIT",
3818
+ "engines": {
3819
+ "node": ">= 0.6"
3820
+ }
3821
+ },
3822
+ "node_modules/mime-types": {
3823
+ "version": "2.1.35",
3824
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
3825
+ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
3826
+ "license": "MIT",
3827
+ "dependencies": {
3828
+ "mime-db": "1.52.0"
3829
+ },
3830
+ "engines": {
3831
+ "node": ">= 0.6"
3832
+ }
3833
+ },
3834
  "node_modules/minimatch": {
3835
  "version": "3.1.2",
3836
  "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
 
4050
  "node": ">= 0.8.0"
4051
  }
4052
  },
4053
+ "node_modules/proxy-from-env": {
4054
+ "version": "1.1.0",
4055
+ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
4056
+ "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
4057
+ "license": "MIT"
4058
+ },
4059
  "node_modules/punycode": {
4060
  "version": "2.3.1",
4061
  "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
Frontend/package.json CHANGED
@@ -13,6 +13,7 @@
13
  "@splinetool/react-spline": "^4.1.0",
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",
 
13
  "@splinetool/react-spline": "^4.1.0",
14
  "@splinetool/runtime": "^1.11.2",
15
  "@tailwindcss/vite": "^4.1.17",
16
+ "axios": "^1.13.2",
17
  "clsx": "^2.1.1",
18
  "dayjs": "^1.11.19",
19
  "framer-motion": "^12.23.24",
Frontend/src/App.tsx CHANGED
@@ -1,69 +1,67 @@
1
- import React, { useState } from "react";
2
  import { BrowserRouter as Router, Routes, Route, Navigate } from "react-router-dom";
 
 
3
  import Dashboard from "./pages/dashboard";
4
  import Notes from "./pages/note";
5
  import AIInterview from "./pages/AiInterview";
6
  import Quize from "./pages/quize";
7
- import Home from "./pages/home";
8
  import Sidebar from "./components/dashboard/Sidebar";
9
 
10
- const App: React.FC = () => {
11
- const [isAuthenticated, setIsAuthenticated] = useState<boolean>(false);
12
 
13
- const handleLogin = () => {
14
- setIsAuthenticated(true);
15
- };
16
-
17
- const handleLogout = () => {
18
- setIsAuthenticated(false);
19
- };
20
 
21
  return (
22
- <Router>
23
- <Routes>
24
 
25
- {/* Public Route */}
26
- <Route
27
- path="/"
28
- element={
29
- isAuthenticated ? (
30
- <Navigate to="/dashboard" replace />
31
- ) : (
32
- <Home onLogin={handleLogin} />
33
- )
34
- }
35
- />
 
36
 
37
- {/* Protected Routes */}
38
- <Route
39
- path="/*"
40
- element={
41
- isAuthenticated ? (
42
- <div className="flex h-screen bg-gray-100">
 
 
 
 
 
 
 
 
 
 
 
 
43
 
44
- {/* Sidebar (only once) */}
45
- <Sidebar onLogout={handleLogout} />
 
 
 
46
 
47
- {/* Main Content */}
48
- <main className="flex-1 overflow-y-auto">
49
- <Routes>
50
- <Route path="/dashboard" element={<Dashboard />} />
51
- <Route path="/notes" element={<Notes />} />
52
- <Route path="/AIInterview" element={<AIInterview />} />
53
- <Route path="/quize" element={<Quize />} />
54
- </Routes>
55
- </main>
56
 
57
- </div>
58
- ) : (
59
- <Navigate to="/" replace />
60
- )
61
- }
62
- />
63
 
64
- </Routes>
65
- </Router>
66
- );
67
  };
68
 
69
  export default App;
 
1
+ import React from "react";
2
  import { BrowserRouter as Router, Routes, Route, Navigate } from "react-router-dom";
3
+
4
+ import Home from "./pages/home";
5
  import Dashboard from "./pages/dashboard";
6
  import Notes from "./pages/note";
7
  import AIInterview from "./pages/AiInterview";
8
  import Quize from "./pages/quize";
 
9
  import Sidebar from "./components/dashboard/Sidebar";
10
 
11
+ import { AuthProvider, useAuth } from "./components/context/AuthContext";
12
+ import ProtectedRoute from "./routes/ProtectedRoute";
13
 
14
+ const DashboardLayout = () => {
15
+ const { logout } = useAuth();
 
 
 
 
 
16
 
17
  return (
18
+ <div className="flex h-screen bg-gray-100">
19
+ <Sidebar onLogout={logout} />
20
 
21
+ <main className="flex-1 overflow-y-auto">
22
+ <Routes>
23
+ <Route path="/dashboard" element={<Dashboard />} />
24
+ <Route path="/notes" element={<Notes />} />
25
+ <Route path="/AIInterview" element={<AIInterview />} />
26
+ <Route path="/quize" element={<Quize />} />
27
+ <Route path="*" element={<Navigate to="/dashboard" />} />
28
+ </Routes>
29
+ </main>
30
+ </div>
31
+ );
32
+ };
33
 
34
+ const App: React.FC = () => {
35
+ return (
36
+ <AuthProvider>
37
+ <Router>
38
+ <Routes>
39
+
40
+ {/* Public Home */}
41
+ <Route path="/" element={<HomeWrapper />} />
42
+
43
+ {/* Protected all dashboard routes */}
44
+ <Route
45
+ path="/*"
46
+ element={
47
+ <ProtectedRoute>
48
+ <DashboardLayout />
49
+ </ProtectedRoute>
50
+ }
51
+ />
52
 
53
+ </Routes>
54
+ </Router>
55
+ </AuthProvider>
56
+ );
57
+ };
58
 
59
+ const HomeWrapper = () => {
60
+ const { isAuthenticated, login } = useAuth();
 
 
 
 
 
 
 
61
 
62
+ if (isAuthenticated) return <Navigate to="/dashboard" replace />;
 
 
 
 
 
63
 
64
+ return <Home onLogin={login} />;
 
 
65
  };
66
 
67
  export default App;
Frontend/src/api/api.ts ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ import axios from "axios";
2
+
3
+ const API = axios.create({
4
+ baseURL: "http://localhost:8000/api/v1",
5
+ });
6
+
7
+ export default API;
Frontend/src/components/auth/SignIn.tsx CHANGED
@@ -1,109 +1,84 @@
1
- import React, { type FormEvent } from 'react'; // FIXED: Use 'type' import for FormEvent
2
- import { Mail, Lock, LogIn, Chrome, X } from 'lucide-react'; // Added 'X' icon for close button
 
3
 
4
  interface SignInProps {
5
  onClose: () => void;
6
  onSwitchToSignUp: () => void;
7
- onAuthSuccess: () => void; // New prop to handle successful auth
8
  }
9
 
10
  const SignIn: React.FC<SignInProps> = ({ onClose, onSwitchToSignUp, onAuthSuccess }) => {
11
-
12
- const handleSubmit = (e: FormEvent) => {
 
 
 
 
13
  e.preventDefault();
14
- // TODO: Add your actual authentication logic here
15
-
16
- // Simulate successful login
17
- onAuthSuccess();
18
- };
19
 
20
- const handleGoogleSignIn = () => {
21
- // TODO: Add Google OAuth logic here
22
- // For now, simulate successful login
23
- onAuthSuccess();
 
 
 
 
 
 
 
24
  };
25
 
26
  return (
27
- <>
28
  <h2 className="text-3xl font-bold mb-8 text-center text-white">
29
  Welcome Back
30
  </h2>
31
 
32
- {/* Sign In Form */}
 
33
  <form className="space-y-5" onSubmit={handleSubmit}>
34
- {/* Email Input */}
35
  <div>
36
- <label htmlFor="email" className="block text-sm font-medium mb-1 text-gray-300">
37
- Email Address
38
- </label>
39
  <div className="relative">
40
- <Mail className="w-5 h-5 absolute left-3 top-1/2 transform -translate-y-1/2 text-blue-400" />
41
  <input
42
- id="email"
43
- type="email"
44
- placeholder="you@example.com"
45
- className="w-full pl-10 pr-4 py-3 border rounded-lg focus:outline-none focus:ring-2 bg-slate-800 border-slate-700 text-white focus:ring-blue-500 transition-colors"
 
46
  required
47
  />
48
  </div>
49
  </div>
50
 
51
- {/* Password Input */}
52
  <div>
53
- <label htmlFor="password" className="block text-sm font-medium mb-1 text-gray-300">
54
- Password
55
- </label>
56
  <div className="relative">
57
- <Lock className="w-5 h-5 absolute left-3 top-1/2 transform -translate-y-1/2 text-blue-400" />
58
  <input
59
- id="password"
60
- type="password"
61
  placeholder="••••••••"
62
- className="w-full pl-10 pr-4 py-3 border rounded-lg focus:outline-none focus:ring-2 bg-slate-800 border-slate-700 text-white focus:ring-blue-500 transition-colors"
 
 
63
  required
64
  />
65
  </div>
66
  </div>
67
 
68
- {/* Sign In Button */}
69
- <button
70
- type="submit"
71
- // FIXED: Changed bg-gradient-to-r to bg-linear-to-r (canonical class)
72
- className="w-full px-5 py-3 rounded-lg bg-linear-to-r from-blue-500 to-gray-500 hover:from-blue-600 hover:to-blue-500 transition shadow-lg shadow-blue-500/50 text-lg font-semibold flex items-center justify-center gap-2 mt-6 text-white"
73
- >
74
  <LogIn className="w-5 h-5" />
75
  Sign In
76
  </button>
77
  </form>
78
 
79
- <div className="flex items-center my-6">
80
- {/* FIXED: Changed flex-grow to grow (canonical class) */}
81
- <div className="grow border-t border-slate-700"></div>
82
- {/* FIXED: Changed flex-shrink to shrink (canonical class) */}
83
- <span className="shrink mx-4 text-sm text-gray-400">OR</span>
84
- {/* FIXED: Changed flex-grow to grow (canonical class) */}
85
- <div className="grow border-t border-slate-700"></div>
86
- </div>
87
-
88
- {/* Social Sign In */}
89
- <button
90
- type="button"
91
- onClick={handleGoogleSignIn}
92
- className="w-full px-5 py-3 rounded-lg border-2 border-blue-400 text-blue-400 hover:bg-blue-400/10 transition-all font-semibold flex items-center justify-center gap-3 bg-slate-900"
93
- >
94
- <Chrome className="w-5 h-5" />
95
- Sign In with Google
96
- </button>
97
-
98
  <p className="mt-8 text-center text-sm text-gray-400">
99
- Don't have an account?
100
- <button
101
- type="button"
102
- onClick={onSwitchToSignUp}
103
- className="ml-2 font-medium text-blue-400 hover:text-blue-300 transition-colors"
104
- >
105
- Sign Up
106
- </button>
107
  </p>
108
  </>
109
  );
 
1
+ import React, { useState, type FormEvent } from "react";
2
+ import { Mail, Lock, LogIn, Chrome } from "lucide-react";
3
+ import API from "../../api/api";
4
 
5
  interface SignInProps {
6
  onClose: () => void;
7
  onSwitchToSignUp: () => void;
8
+ onAuthSuccess: () => void;
9
  }
10
 
11
  const SignIn: React.FC<SignInProps> = ({ onClose, onSwitchToSignUp, onAuthSuccess }) => {
12
+ // const [email, setEmail] = useState("");
13
+ const [username, setUserName] = useState("");
14
+ const [password, setPassword] = useState("");
15
+ const [error, setError] = useState("");
16
+
17
+ const handleSubmit = async (e: FormEvent) => {
18
  e.preventDefault();
19
+ setError("");
 
 
 
 
20
 
21
+ try {
22
+ const res = await API.post("/auth/login", {
23
+ username: username, // 🔥 FastAPI expects `username` (OAuth2PasswordRequestForm)
24
+ password,
25
+ });
26
+
27
+ localStorage.setItem("token", res.data.access_token);
28
+ onAuthSuccess();
29
+ } catch (err: any) {
30
+ setError(err.response?.data?.detail || "Login failed");
31
+ }
32
  };
33
 
34
  return (
35
+ <>
36
  <h2 className="text-3xl font-bold mb-8 text-center text-white">
37
  Welcome Back
38
  </h2>
39
 
40
+ {error && <p className="text-red-400 text-center mb-3">{error}</p>}
41
+
42
  <form className="space-y-5" onSubmit={handleSubmit}>
 
43
  <div>
44
+ <label className="block text-sm mb-1 text-gray-300">Email</label>
 
 
45
  <div className="relative">
46
+ <Mail className="w-5 h-5 absolute left-3 top-1/2 -translate-y-1/2 text-blue-400" />
47
  <input
48
+ type="string"
49
+ placeholder="username or email"
50
+ value={username}
51
+ onChange={(e) => setUserName(e.target.value)}
52
+ className="w-full pl-10 py-3 bg-slate-800 border border-slate-700 text-white rounded-lg"
53
  required
54
  />
55
  </div>
56
  </div>
57
 
 
58
  <div>
59
+ <label className="block text-sm mb-1 text-gray-300">Password</label>
 
 
60
  <div className="relative">
61
+ <Lock className="w-5 h-5 absolute left-3 top-1/2 -translate-y-1/2 text-blue-400" />
62
  <input
63
+ type="string"
 
64
  placeholder="••••••••"
65
+ value={password}
66
+ onChange={(e) => setPassword(e.target.value)}
67
+ className="w-full pl-10 py-3 bg-slate-800 border border-slate-700 text-white rounded-lg"
68
  required
69
  />
70
  </div>
71
  </div>
72
 
73
+ <button className="w-full px-5 py-3 rounded-lg bg-linear-to-r from-blue-500 to-gray-500 text-white flex items-center justify-center gap-2">
 
 
 
 
 
74
  <LogIn className="w-5 h-5" />
75
  Sign In
76
  </button>
77
  </form>
78
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79
  <p className="mt-8 text-center text-sm text-gray-400">
80
+ Dont have an account?
81
+ <button onClick={onSwitchToSignUp} className="ml-2 text-blue-400">Sign Up</button>
 
 
 
 
 
 
82
  </p>
83
  </>
84
  );
Frontend/src/components/auth/SignUp.tsx CHANGED
@@ -1,135 +1,126 @@
1
- // src/components/SignUp.tsx - CORRECTED CODE
2
-
3
- import React from 'react';
4
- import { User, Mail, Lock, UserPlus, Chrome, X } from 'lucide-react';
5
 
6
  interface SignUpProps {
7
- onClose: () => void;
8
- onSwitchToSignIn: () => void;
9
- onAuthSuccess: () => void;
10
  }
11
 
12
- const SignUp: React.FC<SignUpProps> = ({ onClose, onSwitchToSignIn, onAuthSuccess }) => {
13
-
14
- const handleSubmit = (e: React.FormEvent) => {
15
- e.preventDefault();
16
- // ... (Authentication logic remains the same)
17
-
18
- // Simulate successful first-time sign-up (which logs them in)
19
- console.log("Sign Up successful. Logging in and redirecting to dashboard.");
20
- onAuthSuccess();
21
- };
22
-
23
- const handleGoogleSignUp = () => {
24
- // ... (Google Auth logic remains the same)
25
- onAuthSuccess();
26
- };
27
-
28
- return (
29
- <>
30
- <h2 className="text-3xl font-bold mb-8 text-center text-white">
31
- Create Your Account
32
- </h2>
33
- {/* --- Sign Up Form --- */}
34
- <form className="space-y-5" onSubmit={handleSubmit}>
35
- {/* Name Input */}
36
- <div>
37
- <label htmlFor="name" className="block text-sm font-medium mb-1 text-gray-300">Full Name</label>
38
- <div className="relative">
39
- <User className="w-5 h-5 absolute left-3 top-1/2 transform -translate-y-1/2 text-blue-400" />
40
- <input
41
- id="name"
42
- type="text"
43
- placeholder="John Doe"
44
- className="w-full pl-10 pr-4 py-3 border rounded-lg focus:outline-none focus:ring-2 bg-slate-800 border-slate-700 text-white focus:ring-blue-500 transition-colors"
45
- required
46
- />
47
- </div>
48
- </div>
49
-
50
- {/* Email Input */}
51
- <div>
52
- <label htmlFor="email" className="block text-sm font-medium mb-1 text-gray-300">Email Address</label>
53
- <div className="relative">
54
- <Mail className="w-5 h-5 absolute left-3 top-1/2 transform -translate-y-1/2 text-blue-400" />
55
- <input
56
- id="email"
57
- type="email"
58
- placeholder="you@example.com"
59
- className="w-full pl-10 pr-4 py-3 border rounded-lg focus:outline-none focus:ring-2 bg-slate-800 border-slate-700 text-white focus:ring-blue-500 transition-colors"
60
- required
61
- />
62
- </div>
63
- </div>
64
-
65
- {/* Password Input */}
66
- <div>
67
- <label htmlFor="password" className="block text-sm font-medium mb-1 text-gray-300">Password</label>
68
- <div className="relative">
69
- <Lock className="w-5 h-5 absolute left-3 top-1/2 transform -translate-y-1/2 text-blue-400" />
70
- <input
71
- id="password"
72
- type="password"
73
- placeholder="••••••••"
74
- className="w-full pl-10 pr-4 py-3 border rounded-lg focus:outline-none focus:ring-2 bg-slate-800 border-slate-700 text-white focus:ring-blue-500 transition-colors"
75
- required
76
- />
77
- </div>
78
- </div>
79
-
80
- {/* Confirm Password Input */}
81
- <div>
82
- <label htmlFor="confirm-password" className="block text-sm font-medium mb-1 text-gray-300">Confirm Password</label>
83
- <div className="relative">
84
- <Lock className="w-5 h-5 absolute left-3 top-1/2 transform -translate-y-1/2 text-blue-400" />
85
- <input
86
- id="confirm-password"
87
- type="password"
88
- placeholder="••••••••"
89
- className="w-full pl-10 pr-4 py-3 border rounded-lg focus:outline-none focus:ring-2 bg-slate-800 border-slate-700 text-white focus:ring-blue-500 transition-colors"
90
- required
91
- />
92
- </div>
93
- </div>
94
-
95
- {/* Sign Up Button */}
96
- <button
97
- type="submit"
98
- // FIXED: Changed bg-gradient-to-r to bg-linear-to-r (canonical class)
99
- className="w-full px-5 py-3 rounded-lg bg-linear-to-r from-blue-500 to-gray-500 hover:from-blue-600 hover:to-blue-500 transition shadow-lg shadow-blue-500/50 text-lg font-semibold flex items-center justify-center gap-2 mt-6 text-white"
100
- >
101
- <UserPlus className="w-5 h-5" />
102
- Sign Up
103
- </button>
104
- </form>
105
-
106
- <div className="flex items-center my-6">
107
- {/* FIXED: Changed flex-grow to grow (canonical class) */}
108
- <div className="grow border-t border-slate-700"></div>
109
- {/* FIXED: Changed flex-shrink to shrink (canonical class) */}
110
- <span className="shrink mx-4 text-sm text-gray-400">OR</span>
111
- {/* FIXED: Changed flex-grow to grow (canonical class) */}
112
- <div className="grow border-t border-slate-700"></div>
113
- </div>
114
-
115
- {/* --- Social Sign Up --- */}
116
- <button
117
- type="button"
118
- onClick={handleGoogleSignUp}
119
- className="w-full px-5 py-3 rounded-lg border-2 border-blue-400 text-blue-400 hover:bg-blue-400/10 transition-all font-semibold flex items-center justify-center gap-3 bg-slate-900"
120
- >
121
- <Chrome className="w-5 h-5" />
122
- Sign Up with Google
123
- </button>
124
-
125
- <p className="mt-8 text-center text-sm text-gray-400">
126
- Already have an account?
127
- <button type="button" onClick={onSwitchToSignIn} className="ml-2 font-medium text-blue-400 hover:text-blue-300 transition-colors">
128
- Sign In
129
- </button>
130
- </p>
131
- </>
132
- );
133
  };
134
 
135
  export default SignUp;
 
1
+ import React, { useState } from "react";
2
+ import { User, Mail, Lock, UserPlus, Chrome } from "lucide-react";
3
+ import API from "../../api/api";
 
4
 
5
  interface SignUpProps {
6
+ onClose: () => void;
7
+ onSwitchToSignIn: () => void;
8
+ onAuthSuccess: () => void;
9
  }
10
 
11
+ const SignUp: React.FC<SignUpProps> = ({ onSwitchToSignIn, onAuthSuccess }) => {
12
+ const [fullName, setFullName] = useState("");
13
+ const [email, setEmail] = useState("");
14
+ const [password, setPassword] = useState("");
15
+ const [confirm, setConfirm] = useState("");
16
+ const [error, setError] = useState("");
17
+
18
+ const handleSubmit = async (e: React.FormEvent) => {
19
+ e.preventDefault();
20
+ setError("");
21
+
22
+ if (password !== confirm) {
23
+ return setError("Passwords do not match.");
24
+ }
25
+
26
+ try {
27
+ await API.post("/auth/register", {
28
+ full_name: fullName,
29
+ email,
30
+ password,
31
+ });
32
+
33
+ const loginRes = await API.post("/auth/login", {
34
+ username: email,
35
+ password,
36
+ });
37
+
38
+ localStorage.setItem("token", loginRes.data.access_token);
39
+ onAuthSuccess();
40
+ } catch (err: any) {
41
+ setError(err.response?.data?.detail || "Registration failed");
42
+ }
43
+ };
44
+
45
+ return (
46
+ <>
47
+ <h2 className="text-3xl font-bold mb-8 text-center text-white">
48
+ Create Your Account
49
+ </h2>
50
+
51
+ {error && <p className="text-red-400 text-center mb-3">{error}</p>}
52
+
53
+ <form className="space-y-5" onSubmit={handleSubmit}>
54
+ <div>
55
+ <label className="text-gray-300">Full Name</label>
56
+ <div className="relative">
57
+ <User className="w-5 h-5 absolute left-3 top-1/2 -translate-y-1/2 text-blue-400" />
58
+ <input
59
+ value={fullName}
60
+ onChange={(e) => setFullName(e.target.value)}
61
+ type="text"
62
+ className="w-full pl-10 py-3 bg-slate-800 border border-slate-700 text-white rounded-lg"
63
+ required
64
+ />
65
+ </div>
66
+ </div>
67
+
68
+ <div>
69
+ <label className="text-gray-300">Email</label>
70
+ <div className="relative">
71
+ <Mail className="w-5 h-5 absolute left-3 top-1/2 -translate-y-1/2 text-blue-400" />
72
+ <input
73
+ type="email"
74
+ value={email}
75
+ onChange={(e) => setEmail(e.target.value)}
76
+ className="w-full pl-10 py-3 bg-slate-800 border border-slate-700 text-white rounded-lg"
77
+ required
78
+ />
79
+ </div>
80
+ </div>
81
+
82
+ <div>
83
+ <label className="text-gray-300">Password</label>
84
+ <div className="relative">
85
+ <Lock className="w-5 h-5 absolute left-3 top-1/2 -translate-y-1/2 text-blue-400" />
86
+ <input
87
+ type="password"
88
+ value={password}
89
+ onChange={(e) => setPassword(e.target.value)}
90
+ className="w-full pl-10 py-3 bg-slate-800 border border-slate-700 text-white rounded-lg"
91
+ required
92
+ />
93
+ </div>
94
+ </div>
95
+
96
+ <div>
97
+ <label className="text-gray-300">Confirm Password</label>
98
+ <div className="relative">
99
+ <Lock className="w-5 h-5 absolute left-3 top-1/2 -translate-y-1/2 text-blue-400" />
100
+ <input
101
+ type="password"
102
+ value={confirm}
103
+ onChange={(e) => setConfirm(e.target.value)}
104
+ className="w-full pl-10 py-3 bg-slate-800 border border-slate-700 text-white rounded-lg"
105
+ required
106
+ />
107
+ </div>
108
+ </div>
109
+
110
+ <button className="w-full px-5 py-3 rounded-lg bg-linear-to-r from-blue-500 to-gray-500 text-white flex items-center justify-center gap-2">
111
+ <UserPlus className="w-5 h-5" />
112
+ Sign Up
113
+ </button>
114
+ </form>
115
+
116
+ <p className="mt-8 text-center text-sm text-gray-400">
117
+ Already have an account?
118
+ <button onClick={onSwitchToSignIn} className="text-blue-400 ml-2">
119
+ Sign In
120
+ </button>
121
+ </p>
122
+ </>
123
+ );
 
 
 
 
 
 
 
 
124
  };
125
 
126
  export default SignUp;
Frontend/src/components/context/AuthContext.tsx ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React, { createContext, useContext, useState } from "react";
2
+
3
+ interface AuthContextType {
4
+ isAuthenticated: boolean;
5
+ login: () => void;
6
+ logout: () => void;
7
+ }
8
+
9
+ const AuthContext = createContext<AuthContextType | undefined>(undefined);
10
+
11
+ export const AuthProvider = ({ children }: { children: React.ReactNode }) => {
12
+ const [isAuthenticated, setIsAuthenticated] = useState(false);
13
+
14
+ const login = () => setIsAuthenticated(true);
15
+ const logout = () => setIsAuthenticated(false);
16
+
17
+ return (
18
+ <AuthContext.Provider value={{ isAuthenticated, login, logout }}>
19
+ {children}
20
+ </AuthContext.Provider>
21
+ );
22
+ };
23
+
24
+ export const useAuth = () => {
25
+ const ctx = useContext(AuthContext);
26
+ if (!ctx) throw new Error("useAuth must be inside AuthProvider");
27
+ return ctx;
28
+ };
Frontend/src/routes/ProtectedRoute.tsx ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { Navigate } from "react-router-dom";
2
+ import { useAuth } from "../components/context/AuthContext";
3
+
4
+ const ProtectedRoute = ({ children }: { children: React.ReactNode }) => {
5
+ const { isAuthenticated } = useAuth();
6
+
7
+ if (!isAuthenticated) {
8
+ return <Navigate to="/" replace />;
9
+ }
10
+
11
+ return children;
12
+ };
13
+
14
+ export default ProtectedRoute;