diff --git a/package-lock.json b/package-lock.json
index 8dd4151..12efe8e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -14,6 +14,9 @@
"axios": "^1.7.2",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
+ "dompurify": "^3.1.7",
+ "framer-motion": "^11.11.9",
+ "lottie-react": "^2.4.0",
"lucide-react": "^0.400.0",
"next": "^14.2.5",
"radix-ui": "^1.0.1",
@@ -29,6 +32,8 @@
"zod": "^3.23.8"
},
"devDependencies": {
+ "@types/dompurify": "^3.0.5",
+ "@types/js-cookie": "^3.0.6",
"@types/node": "^20.14.9",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
@@ -2810,12 +2815,29 @@
"@babel/types": "^7.20.7"
}
},
+ "node_modules/@types/dompurify": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/@types/dompurify/-/dompurify-3.0.5.tgz",
+ "integrity": "sha512-1Wg0g3BtQF7sSb27fJQAKck1HECM6zV1EB66j8JH9i3LCjYabJa0FSdiSgsD5K/RbrsR0SiraKacLB+T8ZVYAg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/trusted-types": "*"
+ }
+ },
"node_modules/@types/estree": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
"integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==",
"dev": true
},
+ "node_modules/@types/js-cookie": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/@types/js-cookie/-/js-cookie-3.0.6.tgz",
+ "integrity": "sha512-wkw9yd1kEXOPnvEeEV1Go1MmxtBJL0RR79aOTAApecWFVu7w0NNXNqhcWgvw2YgZDYadliXkl14pa3WXw5jlCQ==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@types/lodash": {
"version": "4.17.7",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.7.tgz",
@@ -2863,6 +2885,13 @@
"@types/react": "*"
}
},
+ "node_modules/@types/trusted-types": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz",
+ "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@typescript-eslint/eslint-plugin": {
"version": "7.15.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.15.0.tgz",
@@ -3570,6 +3599,12 @@
"node": ">=6.0.0"
}
},
+ "node_modules/dompurify": {
+ "version": "3.1.7",
+ "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.1.7.tgz",
+ "integrity": "sha512-VaTstWtsneJY8xzy7DekmYWEOZcmzIe3Qb3zPd4STve1OBTa+e+WmS1ITQec1fZYXI3HCsOZZiSMpG6oxoWMWQ==",
+ "license": "(MPL-2.0 OR Apache-2.0)"
+ },
"node_modules/eastasianwidth": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
@@ -4095,6 +4130,31 @@
"url": "https://github.com/sponsors/rawify"
}
},
+ "node_modules/framer-motion": {
+ "version": "11.11.9",
+ "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-11.11.9.tgz",
+ "integrity": "sha512-XpdZseuCrZehdHGuW22zZt3SF5g6AHJHJi7JwQIigOznW4Jg1n0oGPMJQheMaKLC+0rp5gxUKMRYI6ytd3q4RQ==",
+ "license": "MIT",
+ "dependencies": {
+ "tslib": "^2.4.0"
+ },
+ "peerDependencies": {
+ "@emotion/is-prop-valid": "*",
+ "react": "^18.0.0",
+ "react-dom": "^18.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@emotion/is-prop-valid": {
+ "optional": true
+ },
+ "react": {
+ "optional": true
+ },
+ "react-dom": {
+ "optional": true
+ }
+ }
+ },
"node_modules/fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
@@ -4543,6 +4603,25 @@
"loose-envify": "cli.js"
}
},
+ "node_modules/lottie-react": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/lottie-react/-/lottie-react-2.4.0.tgz",
+ "integrity": "sha512-pDJGj+AQlnlyHvOHFK7vLdsDcvbuqvwPZdMlJ360wrzGFurXeKPr8SiRCjLf3LrNYKANQtSsh5dz9UYQHuqx4w==",
+ "license": "MIT",
+ "dependencies": {
+ "lottie-web": "^5.10.2"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0",
+ "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0"
+ }
+ },
+ "node_modules/lottie-web": {
+ "version": "5.12.2",
+ "resolved": "https://registry.npmjs.org/lottie-web/-/lottie-web-5.12.2.tgz",
+ "integrity": "sha512-uvhvYPC8kGPjXT3MyKMrL3JitEAmDMp30lVkuq/590Mw9ok6pWcFCwXJveo0t5uqYw1UREQHofD+jVpdjBv8wg==",
+ "license": "MIT"
+ },
"node_modules/lru-cache": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
diff --git a/package.json b/package.json
index 66da343..4eeea91 100644
--- a/package.json
+++ b/package.json
@@ -16,6 +16,9 @@
"axios": "^1.7.2",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
+ "dompurify": "^3.1.7",
+ "framer-motion": "^11.11.9",
+ "lottie-react": "^2.4.0",
"lucide-react": "^0.400.0",
"next": "^14.2.5",
"radix-ui": "^1.0.1",
@@ -31,6 +34,8 @@
"zod": "^3.23.8"
},
"devDependencies": {
+ "@types/dompurify": "^3.0.5",
+ "@types/js-cookie": "^3.0.6",
"@types/node": "^20.14.9",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
diff --git a/public/assets/todo_pending_animation.json b/public/assets/todo_pending_animation.json
new file mode 100644
index 0000000..2bca429
--- /dev/null
+++ b/public/assets/todo_pending_animation.json
@@ -0,0 +1 @@
+{"v":"5.5.7","meta":{"g":"LottieFiles AE 0.1.20","a":"","k":"","d":"","tc":"#eaedf1"},"fr":60,"ip":0,"op":240,"w":600,"h":600,"nm":"Scanning","ddd":0,"assets":[{"id":"comp_0","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Rectangle Copy 10","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[274,400.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[128,25],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":12.5,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.2,0.2,0.2,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle Copy 3","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":3600,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Rectangle Copy 9","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[368.5,302.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[41,25],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":12.5,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.2,0.2,0.2,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle Copy 5","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":3600,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Rectangle Copy 8","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[348.5,351.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[81,25],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":12.5,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.2,0.2,0.2,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle Copy 4","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":3600,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Rectangle Copy 7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[249,351.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[78,25],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":12.5,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.2,0.2,0.2,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle Copy 2","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":3600,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Rectangle Copy 6","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[270.5,302.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[121,25],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":12.5,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.2,0.2,0.2,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle Copy","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":3600,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"Rectangle 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[255,234.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[90,25],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":12.5,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.2,0.2,0.2,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":3600,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Rectangle 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[299.89,304.75,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[245.78,319.5],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":19,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.48627450980392156,0.3686274509803922,0.9803921568627451,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":3600,"st":0,"bm":0}]},{"id":"comp_1","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Rectangle Copy 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[274,400.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[128,25],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":12.5,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle Copy 3","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":3600,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Rectangle Copy 5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[368.5,302.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[41,25],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":12.5,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle Copy 5","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":3600,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Rectangle Copy 4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[348.5,351.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[81,25],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":12.5,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle Copy 4","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":3600,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Rectangle Copy 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[249,351.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[78,25],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":12.5,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle Copy 2","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":3600,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Rectangle Copy","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[270.5,302.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[121,25],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":12.5,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle Copy","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":3600,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"Rectangle","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[255,234.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[90,25],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":12.5,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":3600,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Rectangle","sr":1,"ks":{"o":{"a":0,"k":60,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[299.89,304.75,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[245.78,319.5],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":19,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.48627450980392156,0.3686274509803922,0.9803921568627451,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":3600,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Rectangle","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.376,"y":1},"o":{"x":0.275,"y":0},"t":0,"s":[300,485.50000000000006,0],"to":[0,-60,0],"ti":[0,0,0]},{"i":{"x":0.725,"y":1},"o":{"x":0.632,"y":0},"t":110,"s":[300,125.49999999999999,0],"to":[0,0,0],"ti":[0,-60,0]},{"t":220,"s":[300,485.50000000000006,0]}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[300,9],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":4.5,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.2,0.2,0.2,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":3600,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"bottom-grad","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":120,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":152,"s":[40]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":199,"s":[40]},{"t":218,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.374,"y":1},"o":{"x":0.274,"y":0},"t":1,"s":[300,463.5,0],"to":[0,-52.833,0],"ti":[0,-7.167,0]},{"i":{"x":0.726,"y":1},"o":{"x":0.621,"y":0},"t":111,"s":[300,146.5,0],"to":[0,7.167,0],"ti":[0,-60,0]},{"t":221,"s":[300,506.50000000000006,0]}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,-100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[300,45],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"gf","o":{"a":0,"k":100,"ix":10},"r":1,"bm":0,"g":{"p":3,"k":{"a":0,"k":[0,0.094,0.439,0.843,0.5,0.094,0.439,0.843,1,0.094,0.439,0.843,0,0,0.252,0.2,0.505,0.4,0.752,0.7,1,1],"ix":9}},"s":{"a":0,"k":[0,-22.5],"ix":5},"e":{"a":0,"k":[0,22.5],"ix":6},"t":1,"nm":"Gradient Fill 1","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":3600,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"top-grad","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":14,"s":[40]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":89,"s":[40]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":108,"s":[0]},{"t":221,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.376,"y":1},"o":{"x":0.271,"y":0},"t":1,"s":[300,463.5,0],"to":[0,-60,0],"ti":[0,0,0]},{"i":{"x":0.725,"y":1},"o":{"x":0.632,"y":0},"t":111,"s":[300,103.49999999999999,0],"to":[0,0,0],"ti":[0,-60,0]},{"t":221,"s":[300,463.5,0]}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[300,45],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"gf","o":{"a":0,"k":100,"ix":10},"r":1,"bm":0,"g":{"p":3,"k":{"a":0,"k":[0,0.094,0.439,0.843,0.5,0.094,0.439,0.843,1,0.094,0.439,0.843,0,0,0.252,0.2,0.505,0.4,0.752,0.7,1,1],"ix":9}},"s":{"a":0,"k":[0,-22.5],"ix":5},"e":{"a":0,"k":[0,22.5],"ix":6},"t":1,"nm":"Gradient Fill 1","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":3600,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":0,"nm":"full","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[300,300,0],"ix":2},"a":{"a":0,"k":[300,300,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"i","pt":{"a":1,"k":[{"i":{"x":0.364,"y":1},"o":{"x":0.272,"y":0},"t":0,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[448.801,109],[153,109],[153,479.957],[448.801,479.957]],"c":true}]},{"i":{"x":0.73,"y":1},"o":{"x":0.631,"y":0},"t":110,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[448.801,109],[153,109],[153,129.957],[448.801,129.957]],"c":true}]},{"t":220,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[448.801,109],[153,109],[153,479.957],[448.801,479.957]],"c":true}]}],"ix":1},"o":{"a":0,"k":100,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 1"}],"w":600,"h":600,"ip":0,"op":3600,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":0,"nm":"trans","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[300,300,0],"ix":2},"a":{"a":0,"k":[300,300,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":600,"h":600,"ip":0,"op":3600,"st":0,"bm":0}],"markers":[]}
\ No newline at end of file
diff --git a/src/App.tsx b/src/App.tsx
index 0921ece..fe4c165 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -1,21 +1,49 @@
import './App.css';
-import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom';
+import { BrowserRouter, Routes, Route } from 'react-router-dom';
+import { useState, useEffect } from 'react';
import Mentors from './pages/root/mentor';
import Login from './pages/auth/Login';
-import Singup from './pages/auth/Singup';
+import Signup from './pages/auth/Singup';
import ForgotPassword from './pages/auth/ForgotPassword';
import Student from './pages/student';
+import Dashboard from './pages/root/dashboard/page';
+import Loader from './pages/root/Loader';
function App() {
+ const [isAuthenticated, setIsAuthenticated] = useState(false);
+ const [isLoading, setIsLoading] = useState(true);
+
+ useEffect(() => {
+ const token = localStorage.getItem('token');
+ setIsAuthenticated(!!token);
+
+
+ setIsLoading(false);
+ }, []);
+
+ if (isLoading) {
+ return ;
+ }
+
return (
- } />
- } />
- } />
- } />
- } />
- } />
+
+ : }
+ />
+ : }
+ />
+ } />
+ } />
+ } />
+ : }
+ />
);
diff --git a/src/actions/planner_actions.ts b/src/actions/planner_actions.ts
new file mode 100644
index 0000000..a66ee00
--- /dev/null
+++ b/src/actions/planner_actions.ts
@@ -0,0 +1,122 @@
+"use server";
+
+import { getCookie } from "./cookie_actions";
+import { revalidateTag } from "next/cache";
+
+export const getPlanner = async () => {
+ const token = await getCookie("token");
+
+ try {
+ const res = await fetch(
+ `${process.env.NEXT_PUBLIC_STUDENT_API_BASE_URL}/api/planner/get`,
+ {
+ method: "GET",
+ headers: {
+ "Content-Type": "application/json",
+ Cookie: `token=${token}`,
+ },
+ credentials: "include",
+ // cache: "force-cache",
+ next: {
+ tags: ["plannerData"],
+ },
+ }
+ );
+
+ const responseData = await res.json();
+
+ return responseData;
+ } catch (error: unknown) {
+ if (error instanceof Error) {
+ throw new Error(`Error fetching planner data: ${error.message}`);
+ } else {
+ throw new Error("An unknown error occurred while fetching planner data!");
+ }
+ }
+};
+
+export const createPlanner = async () => {
+ const token = await getCookie("token");
+
+ try {
+ const res = await fetch(
+ `${process.env.NEXT_PUBLIC_STUDENT_API_BASE_URL}/api/planner/create`,
+ {
+ method: "GET",
+ headers: {
+ "Content-Type": "application/json",
+ Cookie: `token=${token}`,
+ },
+ credentials: "include",
+ }
+ );
+
+ const responseData = await res.json();
+
+ return responseData;
+ } catch (error: unknown) {
+ if (error instanceof Error) {
+ throw new Error(`Error creating planner: ${error.message}`);
+ } else {
+ throw new Error("An unknown error occurred while creating planner!");
+ }
+ }
+};
+
+export const updatePlanner = async () => {
+ const token = await getCookie("token");
+
+ try {
+ const res = await fetch(
+ `${process.env.NEXT_PUBLIC_STUDENT_API_BASE_URL}/api/planner/update`,
+ {
+ method: "GET",
+ headers: {
+ "Content-Type": "application/json",
+ Cookie: `token=${token}`,
+ },
+ credentials: "include",
+ }
+ );
+
+ const responseData = await res.json();
+ revalidateTag("plannerData");
+
+ return responseData;
+ } catch (error: unknown) {
+ if (error instanceof Error) {
+ throw new Error(`Error creating planner: ${error.message}`);
+ } else {
+ throw new Error("An unknown error occurred while creating planner!");
+ }
+ }
+};
+
+export const allocateBackTopics = async () => {
+ const token = await getCookie("token");
+
+ try {
+ const res = await fetch(
+ `${process.env.NEXT_PUBLIC_STUDENT_API_BASE_URL}/api/planner/allocateTopics`,
+ {
+ method: "GET",
+ headers: {
+ "Content-Type": "application/json",
+ Cookie: `token=${token}`,
+ },
+ credentials: "include",
+ }
+ );
+
+ const responseData = await res.json();
+ revalidateTag("plannerData");
+
+ return responseData;
+ } catch (error: unknown) {
+ if (error instanceof Error) {
+ throw new Error(`Error creating planner: ${error.message}`);
+ } else {
+ throw new Error("An unknown error occurred while creating planner!");
+ }
+ }
+};
diff --git a/src/apiClient/apiClient.ts b/src/apiClient/apiClient.ts
index 3abc716..690c9a8 100644
--- a/src/apiClient/apiClient.ts
+++ b/src/apiClient/apiClient.ts
@@ -6,6 +6,7 @@ const apiClient = axios.create({
headers: {
'Content-Type': 'application/json',
},
+
});
apiClient.interceptors.request.use(
diff --git a/src/assets/todo_pending_animation.json b/src/assets/todo_pending_animation.json
new file mode 100644
index 0000000..2bca429
--- /dev/null
+++ b/src/assets/todo_pending_animation.json
@@ -0,0 +1 @@
+{"v":"5.5.7","meta":{"g":"LottieFiles AE 0.1.20","a":"","k":"","d":"","tc":"#eaedf1"},"fr":60,"ip":0,"op":240,"w":600,"h":600,"nm":"Scanning","ddd":0,"assets":[{"id":"comp_0","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Rectangle Copy 10","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[274,400.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[128,25],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":12.5,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.2,0.2,0.2,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle Copy 3","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":3600,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Rectangle Copy 9","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[368.5,302.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[41,25],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":12.5,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.2,0.2,0.2,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle Copy 5","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":3600,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Rectangle Copy 8","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[348.5,351.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[81,25],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":12.5,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.2,0.2,0.2,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle Copy 4","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":3600,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Rectangle Copy 7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[249,351.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[78,25],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":12.5,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.2,0.2,0.2,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle Copy 2","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":3600,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Rectangle Copy 6","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[270.5,302.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[121,25],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":12.5,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.2,0.2,0.2,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle Copy","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":3600,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"Rectangle 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[255,234.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[90,25],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":12.5,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.2,0.2,0.2,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":3600,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Rectangle 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[299.89,304.75,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[245.78,319.5],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":19,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.48627450980392156,0.3686274509803922,0.9803921568627451,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":3600,"st":0,"bm":0}]},{"id":"comp_1","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Rectangle Copy 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[274,400.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[128,25],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":12.5,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle Copy 3","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":3600,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Rectangle Copy 5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[368.5,302.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[41,25],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":12.5,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle Copy 5","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":3600,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Rectangle Copy 4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[348.5,351.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[81,25],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":12.5,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle Copy 4","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":3600,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Rectangle Copy 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[249,351.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[78,25],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":12.5,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle Copy 2","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":3600,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Rectangle Copy","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[270.5,302.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[121,25],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":12.5,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle Copy","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":3600,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"Rectangle","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[255,234.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[90,25],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":12.5,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":3600,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Rectangle","sr":1,"ks":{"o":{"a":0,"k":60,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[299.89,304.75,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[245.78,319.5],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":19,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.48627450980392156,0.3686274509803922,0.9803921568627451,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":3600,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Rectangle","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.376,"y":1},"o":{"x":0.275,"y":0},"t":0,"s":[300,485.50000000000006,0],"to":[0,-60,0],"ti":[0,0,0]},{"i":{"x":0.725,"y":1},"o":{"x":0.632,"y":0},"t":110,"s":[300,125.49999999999999,0],"to":[0,0,0],"ti":[0,-60,0]},{"t":220,"s":[300,485.50000000000006,0]}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[300,9],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":4.5,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.2,0.2,0.2,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":3600,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"bottom-grad","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":120,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":152,"s":[40]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":199,"s":[40]},{"t":218,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.374,"y":1},"o":{"x":0.274,"y":0},"t":1,"s":[300,463.5,0],"to":[0,-52.833,0],"ti":[0,-7.167,0]},{"i":{"x":0.726,"y":1},"o":{"x":0.621,"y":0},"t":111,"s":[300,146.5,0],"to":[0,7.167,0],"ti":[0,-60,0]},{"t":221,"s":[300,506.50000000000006,0]}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,-100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[300,45],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"gf","o":{"a":0,"k":100,"ix":10},"r":1,"bm":0,"g":{"p":3,"k":{"a":0,"k":[0,0.094,0.439,0.843,0.5,0.094,0.439,0.843,1,0.094,0.439,0.843,0,0,0.252,0.2,0.505,0.4,0.752,0.7,1,1],"ix":9}},"s":{"a":0,"k":[0,-22.5],"ix":5},"e":{"a":0,"k":[0,22.5],"ix":6},"t":1,"nm":"Gradient Fill 1","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":3600,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"top-grad","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":14,"s":[40]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":89,"s":[40]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":108,"s":[0]},{"t":221,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.376,"y":1},"o":{"x":0.271,"y":0},"t":1,"s":[300,463.5,0],"to":[0,-60,0],"ti":[0,0,0]},{"i":{"x":0.725,"y":1},"o":{"x":0.632,"y":0},"t":111,"s":[300,103.49999999999999,0],"to":[0,0,0],"ti":[0,-60,0]},{"t":221,"s":[300,463.5,0]}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[300,45],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"gf","o":{"a":0,"k":100,"ix":10},"r":1,"bm":0,"g":{"p":3,"k":{"a":0,"k":[0,0.094,0.439,0.843,0.5,0.094,0.439,0.843,1,0.094,0.439,0.843,0,0,0.252,0.2,0.505,0.4,0.752,0.7,1,1],"ix":9}},"s":{"a":0,"k":[0,-22.5],"ix":5},"e":{"a":0,"k":[0,22.5],"ix":6},"t":1,"nm":"Gradient Fill 1","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":3600,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":0,"nm":"full","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[300,300,0],"ix":2},"a":{"a":0,"k":[300,300,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"i","pt":{"a":1,"k":[{"i":{"x":0.364,"y":1},"o":{"x":0.272,"y":0},"t":0,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[448.801,109],[153,109],[153,479.957],[448.801,479.957]],"c":true}]},{"i":{"x":0.73,"y":1},"o":{"x":0.631,"y":0},"t":110,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[448.801,109],[153,109],[153,129.957],[448.801,129.957]],"c":true}]},{"t":220,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[448.801,109],[153,109],[153,479.957],[448.801,479.957]],"c":true}]}],"ix":1},"o":{"a":0,"k":100,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 1"}],"w":600,"h":600,"ip":0,"op":3600,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":0,"nm":"trans","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[300,300,0],"ix":2},"a":{"a":0,"k":[300,300,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":600,"h":600,"ip":0,"op":3600,"st":0,"bm":0}],"markers":[]}
\ No newline at end of file
diff --git a/src/components/icons/AttachIcon.tsx b/src/components/icons/AttachIcon.tsx
new file mode 100644
index 0000000..8dddad2
--- /dev/null
+++ b/src/components/icons/AttachIcon.tsx
@@ -0,0 +1,23 @@
+import { IIconProps } from "../../helpers/types";
+import { cn } from "../../lib/utils";
+
+const AttachIcon = ({ className, ...props }: IIconProps) => {
+ return (
+
+ );
+};
+
+export default AttachIcon;
diff --git a/src/components/icons/CallIcon.tsx b/src/components/icons/CallIcon.tsx
new file mode 100644
index 0000000..6c6db30
--- /dev/null
+++ b/src/components/icons/CallIcon.tsx
@@ -0,0 +1,20 @@
+import { IIconProps } from "../../helpers/types";
+import { cn } from "../../lib/utils";
+
+const CallIcon = ({ className, ...props }: IIconProps) => {
+ return (
+
+ );
+};
+
+export default CallIcon;
diff --git a/src/components/icons/ChatIcon.tsx b/src/components/icons/ChatIcon.tsx
new file mode 100644
index 0000000..8e4ae8e
--- /dev/null
+++ b/src/components/icons/ChatIcon.tsx
@@ -0,0 +1,25 @@
+import { IIconProps } from "../../helpers/types";
+import { cn } from "../../lib/utils";
+
+const ChatIcon = ({ className, ...props }: IIconProps) => {
+ return (
+
+ );
+};
+
+export default ChatIcon;
diff --git a/src/components/icons/ChatIcon3.tsx b/src/components/icons/ChatIcon3.tsx
new file mode 100644
index 0000000..9ff3006
--- /dev/null
+++ b/src/components/icons/ChatIcon3.tsx
@@ -0,0 +1,20 @@
+import { IIconProps } from "../../helpers/types";
+import { cn } from "../../lib/utils";
+
+const ChatIcon3 = ({ className, ...props }: IIconProps) => {
+ return (
+
+ );
+};
+
+export default ChatIcon3;
diff --git a/src/components/icons/ClockIcon.tsx b/src/components/icons/ClockIcon.tsx
new file mode 100644
index 0000000..7809cd0
--- /dev/null
+++ b/src/components/icons/ClockIcon.tsx
@@ -0,0 +1,20 @@
+import { IIconProps } from "../../helpers/types";
+import { cn } from "../../lib/utils";
+
+const ClockIcon = ({ className, ...props }: IIconProps) => {
+ return (
+
+ );
+};
+
+export default ClockIcon;
diff --git a/src/components/icons/ConferenceMeetingIcon.tsx b/src/components/icons/ConferenceMeetingIcon.tsx
new file mode 100644
index 0000000..670be82
--- /dev/null
+++ b/src/components/icons/ConferenceMeetingIcon.tsx
@@ -0,0 +1,20 @@
+import { IIconProps } from "../../helpers/types";
+import { cn } from "../../lib/utils";
+
+const ConferenceMeetingIcon = ({ className, ...props }: IIconProps) => {
+ return (
+
+ );
+};
+
+export default ConferenceMeetingIcon;
diff --git a/src/components/icons/DashboardIcon.tsx b/src/components/icons/DashboardIcon.tsx
new file mode 100644
index 0000000..e8570ec
--- /dev/null
+++ b/src/components/icons/DashboardIcon.tsx
@@ -0,0 +1,19 @@
+import { IIconProps } from "../../helpers/types";
+import { cn } from "../../lib/utils";
+
+const DashboardIcon = ({ className, ...props }: IIconProps) => {
+ return (
+
+ );
+};
+
+export default DashboardIcon;
diff --git a/src/components/icons/DateIcon.tsx b/src/components/icons/DateIcon.tsx
new file mode 100644
index 0000000..2ac1507
--- /dev/null
+++ b/src/components/icons/DateIcon.tsx
@@ -0,0 +1,24 @@
+import { cn } from '../../lib/utils';
+
+const DateIcon = ({ className }: { className?: string }) => {
+ return (
+
+ );
+};
+
+export default DateIcon;
diff --git a/src/components/icons/DownArrowIcon.tsx b/src/components/icons/DownArrowIcon.tsx
new file mode 100644
index 0000000..d000c48
--- /dev/null
+++ b/src/components/icons/DownArrowIcon.tsx
@@ -0,0 +1,16 @@
+import { IIconProps } from "../../helpers/types";
+import { cn } from "../../lib/utils";
+
+const DownArrowIcon = ({ className, ...props }: IIconProps) => {
+ return (
+
+ );
+};
+
+export default DownArrowIcon;
diff --git a/src/components/icons/EfficiencyIcon.tsx b/src/components/icons/EfficiencyIcon.tsx
new file mode 100644
index 0000000..b09f43f
--- /dev/null
+++ b/src/components/icons/EfficiencyIcon.tsx
@@ -0,0 +1,33 @@
+import { cn } from "../../lib/utils";
+
+
+const EfficiencyIcon = ({ className }: { className?: string }) => {
+ return (
+
+ );
+};
+export default EfficiencyIcon
\ No newline at end of file
diff --git a/src/components/icons/ErrorBookIcon.tsx b/src/components/icons/ErrorBookIcon.tsx
new file mode 100644
index 0000000..9a654a5
--- /dev/null
+++ b/src/components/icons/ErrorBookIcon.tsx
@@ -0,0 +1,20 @@
+import { IIconProps } from "../../helpers/types";
+import { cn } from "../../lib/utils";
+
+const ErrorBookIcon = ({ className, ...props }: IIconProps) => {
+ return (
+
+ );
+};
+
+export default ErrorBookIcon;
diff --git a/src/components/icons/GrowthMeterIcon.tsx b/src/components/icons/GrowthMeterIcon.tsx
new file mode 100644
index 0000000..8e3c24a
--- /dev/null
+++ b/src/components/icons/GrowthMeterIcon.tsx
@@ -0,0 +1,16 @@
+import { IIconProps } from "../../helpers/types";
+import { cn } from "../../lib/utils";
+
+const GrowthMeterIcon = ({ className, ...props }: IIconProps) => {
+ return (
+
+ );
+};
+
+export default GrowthMeterIcon;
diff --git a/src/components/icons/LeftArrowIcon.tsx b/src/components/icons/LeftArrowIcon.tsx
new file mode 100644
index 0000000..4fd594d
--- /dev/null
+++ b/src/components/icons/LeftArrowIcon.tsx
@@ -0,0 +1,16 @@
+import { IIconProps } from "../../helpers/types";
+import { cn } from "../../lib/utils";
+
+const LeftArrowIcon = ({ className, ...props }: IIconProps) => {
+ return (
+
+ );
+};
+
+export default LeftArrowIcon;
diff --git a/src/components/icons/LibertyIcon.tsx b/src/components/icons/LibertyIcon.tsx
new file mode 100644
index 0000000..75d26a2
--- /dev/null
+++ b/src/components/icons/LibertyIcon.tsx
@@ -0,0 +1,20 @@
+import { IIconProps } from "../../helpers/types";
+import { cn } from "../../lib/utils";
+
+const LibertyIcon = ({ className, ...props }: IIconProps) => {
+ return (
+
+ );
+};
+
+export default LibertyIcon;
diff --git a/src/components/icons/MenuIcon.tsx b/src/components/icons/MenuIcon.tsx
new file mode 100644
index 0000000..6a49868
--- /dev/null
+++ b/src/components/icons/MenuIcon.tsx
@@ -0,0 +1,30 @@
+import { IIconProps } from "../../helpers/types";
+import { cn } from "../../lib/utils";
+
+const MenuIcon = ({ className, ...props }: IIconProps) => {
+ return (
+
+ );
+};
+
+export default MenuIcon;
diff --git a/src/components/icons/MicIcon.tsx b/src/components/icons/MicIcon.tsx
new file mode 100644
index 0000000..69d9017
--- /dev/null
+++ b/src/components/icons/MicIcon.tsx
@@ -0,0 +1,34 @@
+import { IIconProps } from "../../helpers/types";
+import { cn } from "../../lib/utils";
+
+const MicIcon = ({ className, ...props }: IIconProps) => {
+ return (
+
+ );
+};
+
+export default MicIcon;
diff --git a/src/components/icons/NotificationIcon.tsx b/src/components/icons/NotificationIcon.tsx
new file mode 100644
index 0000000..d64b56e
--- /dev/null
+++ b/src/components/icons/NotificationIcon.tsx
@@ -0,0 +1,20 @@
+import { IIconProps } from "../../helpers/types";
+import { cn } from "../../lib/utils";
+
+const NotificationIcon = ({ className, ...props }: IIconProps) => {
+ return (
+
+ );
+};
+
+export default NotificationIcon;
diff --git a/src/components/icons/OneOnOneMeetingIcon.tsx b/src/components/icons/OneOnOneMeetingIcon.tsx
new file mode 100644
index 0000000..a112310
--- /dev/null
+++ b/src/components/icons/OneOnOneMeetingIcon.tsx
@@ -0,0 +1,20 @@
+import { IIconProps } from "../../helpers/types";
+import { cn } from "../../lib/utils";
+
+const OneOnOneMeetingIcon = ({ className, ...props }: IIconProps) => {
+ return (
+
+ );
+};
+
+export default OneOnOneMeetingIcon;
diff --git a/src/components/icons/PlannerIcon.tsx b/src/components/icons/PlannerIcon.tsx
new file mode 100644
index 0000000..d6f2b2b
--- /dev/null
+++ b/src/components/icons/PlannerIcon.tsx
@@ -0,0 +1,25 @@
+import { IIconProps } from "../../helpers/types";
+import { cn } from "../../lib/utils";
+
+const PlannerIcon = ({ className, ...props }: IIconProps) => {
+ return (
+
+ );
+};
+
+export default PlannerIcon;
diff --git a/src/components/icons/Questionicon.tsx b/src/components/icons/Questionicon.tsx
new file mode 100644
index 0000000..6e22c7c
--- /dev/null
+++ b/src/components/icons/Questionicon.tsx
@@ -0,0 +1,24 @@
+import { cn } from '../../lib/utils';
+
+const QuestionIcon = ({ className }: { className?: string }) => {
+ return (
+
+ );
+};
+
+export default QuestionIcon;
diff --git a/src/components/icons/QuizIcon.tsx b/src/components/icons/QuizIcon.tsx
new file mode 100644
index 0000000..71263a6
--- /dev/null
+++ b/src/components/icons/QuizIcon.tsx
@@ -0,0 +1,20 @@
+import { IIconProps } from "../../helpers/types";
+import { cn } from "../../lib/utils";
+
+const QuizIcon = ({ className, ...props }: IIconProps) => {
+ return (
+
+ );
+};
+
+export default QuizIcon;
diff --git a/src/components/icons/RequestMeetingIcon.tsx b/src/components/icons/RequestMeetingIcon.tsx
new file mode 100644
index 0000000..bec1311
--- /dev/null
+++ b/src/components/icons/RequestMeetingIcon.tsx
@@ -0,0 +1,20 @@
+import { IIconProps } from "../../helpers/types";
+import { cn } from "../../lib/utils";
+
+const RequestMeetingIcon = ({ className, ...props }: IIconProps) => {
+ return (
+
+ );
+};
+
+export default RequestMeetingIcon;
diff --git a/src/components/icons/RightArrowIcon.tsx b/src/components/icons/RightArrowIcon.tsx
new file mode 100644
index 0000000..46a7b93
--- /dev/null
+++ b/src/components/icons/RightArrowIcon.tsx
@@ -0,0 +1,28 @@
+import { IIconProps } from "../../helpers/types";
+import { cn } from "../../lib/utils";
+
+const RightArrowIcon = ({ className, ...props }: IIconProps) => {
+ return (
+
+ );
+};
+
+export default RightArrowIcon;
diff --git a/src/components/icons/SendIcon.tsx b/src/components/icons/SendIcon.tsx
new file mode 100644
index 0000000..e785446
--- /dev/null
+++ b/src/components/icons/SendIcon.tsx
@@ -0,0 +1,24 @@
+import { IIconProps } from "../../helpers/types";
+import { cn } from "../../lib/utils";
+
+const SendIcon = ({ className, ...props }: IIconProps) => {
+ return (
+
+ );
+};
+
+export default SendIcon;
diff --git a/src/components/icons/StudyRoomIcon.tsx b/src/components/icons/StudyRoomIcon.tsx
new file mode 100644
index 0000000..178d280
--- /dev/null
+++ b/src/components/icons/StudyRoomIcon.tsx
@@ -0,0 +1,17 @@
+import { IIconProps } from "../../helpers/types";
+import { cn } from "../../lib/utils";
+
+const StudyRoomIcon = ({ className, ...props }: IIconProps) => {
+ return (
+
+ );
+};
+
+export default StudyRoomIcon;
diff --git a/src/components/icons/TimeIcon.tsx b/src/components/icons/TimeIcon.tsx
new file mode 100644
index 0000000..a1786ce
--- /dev/null
+++ b/src/components/icons/TimeIcon.tsx
@@ -0,0 +1,21 @@
+import { cn } from "../../lib/utils";
+
+const TimeIcon = ({ className }: { className?: string }) => {
+ return (
+
+ );
+};
+
+export default TimeIcon;
diff --git a/src/components/icons/TrackerIcon.tsx b/src/components/icons/TrackerIcon.tsx
new file mode 100644
index 0000000..c40106d
--- /dev/null
+++ b/src/components/icons/TrackerIcon.tsx
@@ -0,0 +1,20 @@
+import { IIconProps } from "../../helpers/types";
+import { cn } from "../../lib/utils";
+
+const TrackerIcon = ({ className, ...props }: IIconProps) => {
+ return (
+
+ );
+};
+
+export default TrackerIcon;
diff --git a/src/components/icons/TrophyIcon.tsx b/src/components/icons/TrophyIcon.tsx
new file mode 100644
index 0000000..df709ea
--- /dev/null
+++ b/src/components/icons/TrophyIcon.tsx
@@ -0,0 +1,28 @@
+import { cn } from '../../lib/utils';
+
+const TrophyIcon = ({ className }: { className?: string }) => {
+ return (
+
+ );
+};
+export default TrophyIcon;
diff --git a/src/components/icons/UpArrowIcon.tsx b/src/components/icons/UpArrowIcon.tsx
new file mode 100644
index 0000000..e0a5fab
--- /dev/null
+++ b/src/components/icons/UpArrowIcon.tsx
@@ -0,0 +1,16 @@
+import { IIconProps } from "../../helpers/types";
+import { cn } from "../../lib/utils";
+
+const UpArrowIcon = ({ className, ...props }: IIconProps) => {
+ return (
+
+ );
+};
+
+export default UpArrowIcon;
diff --git a/src/components/icons/VideoChatIcon.tsx b/src/components/icons/VideoChatIcon.tsx
new file mode 100644
index 0000000..ffaa2ea
--- /dev/null
+++ b/src/components/icons/VideoChatIcon.tsx
@@ -0,0 +1,16 @@
+import { IIconProps } from "../../helpers/types";
+import { cn } from "../../lib/utils";
+
+const VideoChatIcon = ({ className, ...props }: IIconProps) => {
+ return (
+
+ );
+};
+
+export default VideoChatIcon;
diff --git a/src/components/icons/WorkshopIcon.tsx b/src/components/icons/WorkshopIcon.tsx
new file mode 100644
index 0000000..42ab8d7
--- /dev/null
+++ b/src/components/icons/WorkshopIcon.tsx
@@ -0,0 +1,20 @@
+import { IIconProps } from "../../helpers/types";
+import { cn } from "../../lib/utils";
+
+const WorkshopIcon = ({ className, ...props }: IIconProps) => {
+ return (
+
+ );
+};
+
+export default WorkshopIcon;
diff --git a/src/components/index.ts b/src/components/index.ts
new file mode 100644
index 0000000..06dba63
--- /dev/null
+++ b/src/components/index.ts
@@ -0,0 +1,71 @@
+import Container from "./shared/Container";
+import Logo from "./shared/Logo";
+import Header from "./shared/Header";
+import SidebarDesktop from "./shared/SidebarDesktop";
+import Sidebar from "./shared/Sidebar";
+import TabNavItem from "./shared/TabNavItem";
+import TabContent from "./shared/TabContent";
+import MobileNavBar from "./shared/MobileNavBar";
+import MobileMenu from "./shared/MobileMenu";
+import Input from "./shared/Input";
+
+// import SemiRadialChart from "./charts/SemiRadialChart";
+// import RadialBarChart from "./charts/RadialBarChart";
+// import BarChart from "./charts/BarChart";
+// import MonthlyReportChart from "./charts/MonthlyReportChart";
+// import OverallReportChart from "./charts/OverallReportChart";
+// import DonutChart from "./charts/DonutChart";
+
+import RightArrowIcon from "./icons/RightArrowIcon";
+import LeftArrowIcon from "./icons/LeftArrowIcon";
+import NotificationIcon from "./icons/NotificationIcon";
+import ChatIcon from "./icons/ChatIcon";
+import VideoChatIcon from "./icons/VideoChatIcon";
+import RequestMeetingIcon from "./icons/RequestMeetingIcon";
+import UpArrowIcon from "./icons/UpArrowIcon";
+import DownArrowIcon from "./icons/DownArrowIcon";
+import AttachIcon from "./icons/AttachIcon";
+import CallIcon from "./icons/CallIcon";
+import ChatIcon3 from "./icons/ChatIcon3";
+import MenuIcon from "./icons/MenuIcon";
+import MicIcon from "./icons/MicIcon";
+import SendIcon from "./icons/SendIcon";
+import OneOnOneMeetingIcon from "./icons/OneOnOneMeetingIcon";
+import ConferenceMeetingIcon from "./icons/ConferenceMeetingIcon";
+import ClockIcon from "./icons/ClockIcon";
+
+export {
+ Container,
+ Logo,
+ Header,
+ SidebarDesktop,
+ Sidebar,
+ TabNavItem,
+ TabContent,
+ MobileNavBar,
+ MobileMenu,
+ Input,
+ // SemiRadialChart,
+ // RadialBarChart,
+ // BarChart,
+ // MonthlyReportChart,
+ // OverallReportChart,
+ // DonutChart,
+ RightArrowIcon,
+ LeftArrowIcon,
+ NotificationIcon,
+ ChatIcon,
+ VideoChatIcon,
+ RequestMeetingIcon,
+ UpArrowIcon,
+ DownArrowIcon,
+ AttachIcon,
+ CallIcon,
+ ChatIcon3,
+ MenuIcon,
+ MicIcon,
+ SendIcon,
+ OneOnOneMeetingIcon,
+ ConferenceMeetingIcon,
+ ClockIcon,
+};
diff --git a/src/components/shared/ComingSoon.tsx b/src/components/shared/ComingSoon.tsx
new file mode 100644
index 0000000..f1f6893
--- /dev/null
+++ b/src/components/shared/ComingSoon.tsx
@@ -0,0 +1,18 @@
+import Header from "./Header";
+
+const ComingSoon = ({ pageTitle }: { pageTitle: string }) => {
+ return (
+
+ );
+};
+
+export default ComingSoon;
diff --git a/src/components/shared/Container.tsx b/src/components/shared/Container.tsx
new file mode 100644
index 0000000..a9b5b4f
--- /dev/null
+++ b/src/components/shared/Container.tsx
@@ -0,0 +1,10 @@
+import { TContainerProps } from "../../helpers/types";
+import { cn } from "../../lib/utils";
+
+const Container = ({ children, className }: TContainerProps) => {
+ return (
+
{children}
+ );
+};
+
+export default Container;
diff --git a/src/components/shared/Header.tsx b/src/components/shared/Header.tsx
new file mode 100644
index 0000000..05619dc
--- /dev/null
+++ b/src/components/shared/Header.tsx
@@ -0,0 +1,22 @@
+import { THeaderProps } from "../../helpers/types";
+import { cn } from "../../lib/utils";
+
+const Header = ({
+ title,
+ className,
+ icon: Icon,
+ titleClassName,
+}: THeaderProps) => {
+ return (
+
+ {title}
+ {Icon && {Icon}
}
+
+ );
+};
+
+export default Header;
diff --git a/src/components/shared/Input.tsx b/src/components/shared/Input.tsx
new file mode 100644
index 0000000..23d7b84
--- /dev/null
+++ b/src/components/shared/Input.tsx
@@ -0,0 +1,51 @@
+import { cn } from "../../lib/utils";
+
+import React, {
+ ForwardRefRenderFunction,
+ InputHTMLAttributes,
+ forwardRef,
+ useId,
+} from "react";
+
+interface InputProps extends InputHTMLAttributes {
+ label?: string;
+ icon1?: React.ReactNode;
+ icon2?: React.ReactNode;
+}
+
+const Input: ForwardRefRenderFunction = (
+ {
+ label,
+ className = "",
+ type = "text",
+ placeholder = "",
+ icon1,
+ icon2,
+ ...props
+ },
+ ref
+) => {
+ const id = useId();
+
+ return (
+
+ {label &&
}
+
+ {icon1 && icon1}
+
+
+
+ {icon2 && icon2}
+
+
+ );
+};
+
+export default forwardRef(Input);
diff --git a/src/components/shared/Loader.tsx b/src/components/shared/Loader.tsx
new file mode 100644
index 0000000..9b42651
--- /dev/null
+++ b/src/components/shared/Loader.tsx
@@ -0,0 +1,11 @@
+import { Loader2 } from "lucide-react";
+
+const Loader = () => {
+ return (
+
+
+
+ );
+};
+
+export default Loader;
diff --git a/src/components/shared/Logo.tsx b/src/components/shared/Logo.tsx
new file mode 100644
index 0000000..cab5282
--- /dev/null
+++ b/src/components/shared/Logo.tsx
@@ -0,0 +1,34 @@
+import Image from "next/image";
+
+import { TLogoProps } from "../../helpers/types";
+import { cn } from "../../lib/utils";
+
+const Logo = ({
+ fullLogoWidth,
+ fullLogoHeight,
+ fullLogoClassName,
+ smallLogoWidth,
+ smallLogoHeight,
+ smallLogoClassName,
+}: TLogoProps) => {
+ return (
+ <>
+
+
+ >
+ );
+};
+
+export default Logo;
diff --git a/src/components/shared/LogoutButton.tsx b/src/components/shared/LogoutButton.tsx
new file mode 100644
index 0000000..1ae6777
--- /dev/null
+++ b/src/components/shared/LogoutButton.tsx
@@ -0,0 +1,50 @@
+"use client";
+
+import { useRouter } from "next/navigation";
+
+import { LogOut } from "lucide-react";
+
+import { toast } from "sonner";
+
+import { Button } from "../ui/button";
+
+// import { useAppDispatch } from "@/redux/hooks";
+// import { userData } from "@/redux/slices/userSlice";
+
+const LogoutButton = () => {
+ const router = useRouter();
+
+ // const dispatch = useAppDispatch();
+
+ const logoutHandler = async () => {
+ try {
+ const response = await fetch("/api/auth/logout", {
+ method: "Get",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ });
+
+ const responseData = await response.json();
+ toast.success(responseData.message);
+ router.push("/login");
+ // dispatch(userData(null));
+ } catch (error: any) {
+ toast.error("Logout Failed!", {
+ description: error?.message,
+ });
+ }
+ };
+ return (
+
+ );
+};
+
+export default LogoutButton;
diff --git a/src/components/shared/MobileMenu.tsx b/src/components/shared/MobileMenu.tsx
new file mode 100644
index 0000000..6fa834e
--- /dev/null
+++ b/src/components/shared/MobileMenu.tsx
@@ -0,0 +1,125 @@
+"use client";
+
+import React, { useEffect, useRef, useState } from "react";
+import Link from "next/link";
+import { usePathname } from "next/navigation";
+
+import { motion } from "framer-motion";
+
+import { userSidebarLinks } from "../../helpers/constants";
+import { cn } from "../../lib/utils";
+
+const MobileMenu = ({ meetingsLength }: { meetingsLength: number }) => {
+ const [navScrollPosition, setNavScrollPosition] = useState(0);
+ const navbarRef = useRef(null);
+
+ const pathname = usePathname();
+
+ useEffect(() => {
+ const handleScroll = () => {
+ if (navbarRef.current) {
+ setNavScrollPosition(navbarRef.current.scrollLeft);
+ }
+ };
+
+ if (navbarRef.current) {
+ navbarRef.current.addEventListener("scroll", handleScroll);
+ }
+
+ return () => {
+ if (navbarRef.current) {
+ navbarRef.current.removeEventListener("scroll", handleScroll);
+ }
+ };
+ }, []);
+
+ const handleMenuItemClick = (e: React.MouseEvent) => {
+ const clickedItem = e.currentTarget;
+ const navbarWidth = navbarRef.current?.offsetWidth || 0;
+ const clickedItemRect = clickedItem.getBoundingClientRect();
+ const isLastVisibleItem =
+ clickedItemRect.right >= navbarWidth + navScrollPosition;
+ const isFirstVisibleItem = clickedItemRect.left <= navScrollPosition;
+
+ if (navbarRef.current) {
+ if (isLastVisibleItem) {
+ const newScrollPosition = clickedItemRect.left - navbarWidth / 5;
+ navbarRef.current.scrollTo({
+ left: newScrollPosition,
+ behavior: "smooth",
+ });
+ } else if (isFirstVisibleItem) {
+ const newScrollPosition = clickedItemRect.right - navbarWidth / 5;
+ navbarRef.current.scrollTo({
+ left: newScrollPosition,
+ behavior: "smooth",
+ });
+ }
+ }
+ };
+
+ return (
+
+ );
+};
+
+export default MobileMenu;
diff --git a/src/components/shared/MobileNavBar.tsx b/src/components/shared/MobileNavBar.tsx
new file mode 100644
index 0000000..815455b
--- /dev/null
+++ b/src/components/shared/MobileNavBar.tsx
@@ -0,0 +1,49 @@
+import Image from "next/image";
+import Link from "next/link";
+
+// import { Logo, NotificationIcon } from "@/components";
+
+const MobileNavBar = () => {
+ return (
+
+ );
+};
+
+export default MobileNavBar;
diff --git a/src/components/shared/Modal.tsx b/src/components/shared/Modal.tsx
new file mode 100644
index 0000000..250bf8f
--- /dev/null
+++ b/src/components/shared/Modal.tsx
@@ -0,0 +1,27 @@
+"use client";
+
+import React from "react";
+import { Dialog, DialogContent, DialogOverlay } from "../ui/dialog";
+
+const Modal = ({
+ children,
+ setOpenDialogBox,
+}: {
+ children: React.ReactNode;
+ setOpenDialogBox: (openDialogBox: boolean) => void;
+}) => {
+ const handleOpenChange = () => {
+ setOpenDialogBox(false);
+ };
+ return (
+
+ );
+};
+
+export default Modal;
diff --git a/src/components/shared/MotionDiv.tsx b/src/components/shared/MotionDiv.tsx
new file mode 100644
index 0000000..1c32996
--- /dev/null
+++ b/src/components/shared/MotionDiv.tsx
@@ -0,0 +1,5 @@
+"use client";
+
+import { motion } from "framer-motion";
+
+export const MotionDiv = motion.div;
diff --git a/src/components/shared/OtpInput.tsx b/src/components/shared/OtpInput.tsx
new file mode 100644
index 0000000..b19d701
--- /dev/null
+++ b/src/components/shared/OtpInput.tsx
@@ -0,0 +1,31 @@
+// OtpInput.tsx
+
+import React from 'react';
+
+const OtpInput = () => {
+ // Handle key press events to move focus
+ const handleKeyUp = (e: React.KeyboardEvent, index: number) => {
+ if (e.currentTarget.value.length === 1) {
+ const nextInput = document.querySelectorAll('input')[index + 1];
+ if (nextInput) nextInput.focus();
+ }
+ };
+
+ return (
+
+ {Array.from({ length: 4 }).map((_, index) => (
+ handleKeyUp(e, index)}
+ />
+ ))}
+
+ );
+};
+
+export default OtpInput;
diff --git a/src/components/shared/Sidebar.tsx b/src/components/shared/Sidebar.tsx
new file mode 100644
index 0000000..630cac8
--- /dev/null
+++ b/src/components/shared/Sidebar.tsx
@@ -0,0 +1,18 @@
+import React from "react";
+import SidebarDesktop from "./SidebarDesktop"; // Ensure this path is correct
+import { userSidebarLinks } from "../../helpers/constants"; // Adjust path if necessary
+
+type SidebarProps = {
+ meetingsLength: number; // TypeScript prop definition
+};
+
+const Sidebar: React.FC = ({ meetingsLength }) => {
+ return (
+
+ );
+};
+
+export default Sidebar;
diff --git a/src/components/shared/SidebarDesktop.tsx b/src/components/shared/SidebarDesktop.tsx
new file mode 100644
index 0000000..d636958
--- /dev/null
+++ b/src/components/shared/SidebarDesktop.tsx
@@ -0,0 +1,93 @@
+"use client";
+import Link from "next/link";
+import { usePathname } from "next/navigation";
+import { motion } from "framer-motion";
+
+import { Logo } from "../../components";
+import { TSidebarLink } from "../../helpers/types";
+import { cn } from "../../lib/utils";
+// import { Button } from "../ui/button";
+// import { LogOut } from "lucide-react";
+// import LogoutButton from "./LogoutButton";
+
+type SidebarDesktopProps = {
+ sidebar: TSidebarLink[];
+ meetingsLength: number;
+};
+const SidebarDesktop: React.FC = ({ sidebar, meetingsLength }) => {
+ const pathname = usePathname();
+ return (
+
+ );
+};
+
+export default SidebarDesktop;
diff --git a/src/components/shared/TabContent.tsx b/src/components/shared/TabContent.tsx
new file mode 100644
index 0000000..635cdb0
--- /dev/null
+++ b/src/components/shared/TabContent.tsx
@@ -0,0 +1,46 @@
+"use client";
+
+import { AnimatePresence, motion, Variants } from "framer-motion";
+
+import { TTabContentProps } from "../../helpers/types";
+import { cn } from "../../lib/utils";
+
+const tabContentVariants: Variants = {
+ initial: {
+ x: 0,
+ opacity: 1,
+ },
+ enter: {
+ x: 0,
+ opacity: 1,
+ },
+ exit: {
+ x: -100,
+ opacity: 0,
+ },
+};
+
+const TabContent = ({
+ id,
+ activeTab,
+ children,
+ className,
+}: TTabContentProps) => {
+ return activeTab === id ? (
+
+
+ {children}
+
+
+ ) : null;
+};
+
+export default TabContent;
diff --git a/src/components/shared/TabNavItem.tsx b/src/components/shared/TabNavItem.tsx
new file mode 100644
index 0000000..3215c72
--- /dev/null
+++ b/src/components/shared/TabNavItem.tsx
@@ -0,0 +1,46 @@
+"use client";
+
+import { motion } from "framer-motion";
+import { TTabNavItemProps } from "../../helpers/types";
+import { cn } from "../../lib/utils";
+
+const TabNavItem = ({
+ id,
+ title,
+ activeTab,
+ setActiveTab,
+ className,
+ activeTabClassName,
+ titleClassName,
+ layoutIdPrefix,
+}: TTabNavItemProps) => {
+ const handleClick = () => {
+ setActiveTab(id);
+ };
+
+ const layoutId = `${layoutIdPrefix}_active__tab`;
+
+ return (
+
+ {activeTab === id && (
+
+ )}
+ {title}
+
+ );
+};
+
+export default TabNavItem;
diff --git a/src/components/ui/button.tsx b/src/components/ui/button.tsx
index 0ba4277..4106711 100644
--- a/src/components/ui/button.tsx
+++ b/src/components/ui/button.tsx
@@ -2,7 +2,7 @@ import * as React from "react"
import { Slot } from "@radix-ui/react-slot"
import { cva, type VariantProps } from "class-variance-authority"
-import { cn } from "@/lib/utils"
+import { cn } from "../../lib/utils"
const buttonVariants = cva(
"inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
diff --git a/src/helpers/constants/efficiency.ts b/src/helpers/constants/efficiency.ts
new file mode 100644
index 0000000..3b81ee0
--- /dev/null
+++ b/src/helpers/constants/efficiency.ts
@@ -0,0 +1,73 @@
+import { EfficiencyOption } from ".";
+export const efficiencyOptions: EfficiencyOption[] = [
+ {
+ max: 30,
+ label: '0-30%',
+ progressBarColor: 'bg-red-500',
+ textColor: 'text-red-500',
+ },
+ {
+ min: 30,
+ max: 50,
+ label: '30-50%',
+ progressBarColor: 'bg-orange-500',
+ textColor: 'text-orange-500',
+ },
+ {
+ min: 50,
+ max: 70,
+ label: '50-70%',
+ progressBarColor: 'bg-yellow-500',
+ textColor: 'text-yellow-500',
+ },
+ {
+ min: 70,
+ max: 90,
+ label: '70-90%',
+ progressBarColor: 'bg-orange-300',
+ textColor: 'text-orange-300',
+ },
+ {
+ min: 90,
+ label: '90-100%',
+ progressBarColor: 'bg-green-400',
+ textColor: 'text-green-400',
+ },
+];
+
+
+function findEfficiencyOption(
+ efficiency: number
+): EfficiencyOption | undefined {
+ if (isNaN(efficiency)) {
+ throw new Error("Efficiency must be a number.");
+ }
+
+ return efficiencyOptions.find((opt) => {
+ if (opt.min !== undefined && opt.max !== undefined) {
+ return efficiency >= opt.min && efficiency < opt.max;
+ } else if (opt.min !== undefined) {
+ return efficiency >= opt.min;
+ } else if (opt.max !== undefined) {
+ return efficiency < opt.max;
+ }
+ return false;
+ });
+}
+
+export function getProgressBarColor(efficiency: number): string {
+ const option = findEfficiencyOption(efficiency);
+ if (!option) {
+ return 'bg-[#ffffff]';
+ }
+
+ return option.progressBarColor;
+}
+export function getTextColor(efficiency: number): string {
+ const option = findEfficiencyOption(efficiency);
+ if (!option) {
+ return 'text-red-500'
+ }
+
+ return option.textColor;
+}
diff --git a/src/helpers/constants/index.ts b/src/helpers/constants/index.ts
new file mode 100644
index 0000000..1684bbb
--- /dev/null
+++ b/src/helpers/constants/index.ts
@@ -0,0 +1,188 @@
+import { TSidebarLink } from "../types";
+
+import DashboardIcon from "../../components/icons/DashboardIcon";
+import PlannerIcon from "../../components/icons/PlannerIcon";
+import TrackerIcon from "../../components/icons/TrackerIcon";
+import ErrorBookIcon from "../../components/icons/ErrorBookIcon";
+import GrowthMeterIcon from "../../components/icons/GrowthMeterIcon";
+import WorkshopIcon from "../../components/icons/WorkshopIcon";
+import LibertyIcon from "../../components/icons/LibertyIcon";
+import QuizIcon from "../../components/icons/QuizIcon";
+import StudyRoomIcon from "../../components/icons/StudyRoomIcon";
+import ChatIcon3 from "../../components/icons/ChatIcon3";
+
+export const userSidebarLinks: TSidebarLink[] = [
+ {
+ label: "dashboard",
+ icon: DashboardIcon,
+ href: "/",
+ },
+ {
+ label: "planner",
+ icon: PlannerIcon,
+ href: "/planner",
+ },
+ {
+ label: "tracker",
+ icon: TrackerIcon,
+ href: "/tracker",
+ },
+ {
+ label: "chat",
+ icon: ChatIcon3,
+ href: "/chat",
+ },
+ {
+ label: "quizzes",
+ icon: QuizIcon,
+ href: "/quizzes",
+ },
+ {
+ label: "errorbook",
+ icon: ErrorBookIcon,
+ href: "/error-book",
+ },
+ {
+ label: "growth meter",
+ icon: GrowthMeterIcon,
+ href: "/growth-meter",
+ },
+ {
+ label: "workshops",
+ icon: WorkshopIcon,
+ href: "/workshops",
+ },
+ {
+ label: "library",
+ icon: LibertyIcon,
+ href: "/library",
+ },
+ {
+ label: "study room",
+ icon: StudyRoomIcon,
+ href: "/study-room",
+ },
+];
+
+export const moodEmojis = [
+ {
+ moodImg: "/assets/icons/sad_emoji.png",
+ mood_id: "sad-emoji",
+ mood: "sad",
+ },
+ {
+ moodImg: "/assets/icons/unhappy_emoji.png",
+ mood_id: "unhappy-emoji",
+ mood: "unhappy",
+ },
+ {
+ moodImg: "/assets/icons/neutral_emoji.png",
+ mood_id: "neutral-emoji",
+ mood: "neutral",
+ },
+ {
+ moodImg: "/assets/icons/smiling_emoji.png",
+ mood: "smiling",
+ mood_id: "smiling-emoji",
+ },
+ {
+ moodImg: "/assets/icons/laughing_emoji.png",
+ mood_id: "laughing-emoji",
+ mood: "laughing",
+ },
+];
+
+export const manageAccountTabs = [
+ {
+ id: "personal-info",
+ label: "Personal Info",
+ },
+ {
+ id: "study-progress",
+ label: "Study Progress",
+ },
+ // {
+ // id: "subject-overview",
+ // label: "Subject Overview",
+ // },
+ // {
+ // id: "your-mentor",
+ // label: "Your Mentor",
+ // },
+];
+
+export const subscriptionPlanningBenefits = [
+ {
+ label: "goal setting & tracking",
+ },
+ {
+ label: "schedule builder",
+ },
+ {
+ label: "to-do list & reminders",
+ },
+ {
+ label: "subject, chapter & topic tracking",
+ },
+];
+
+export const subscriptionExpertBenefits = [
+ {
+ label: "connect with a mentor",
+ },
+ {
+ label: "live & on-demand workshops",
+ },
+];
+export const subscriptionLearningBenefits = [
+ {
+ label: "growth meter",
+ },
+ {
+ label: "points & levels",
+ },
+ {
+ label: "know your mistakes",
+ },
+];
+export interface EfficiencyOption {
+ min?: number;
+ max?: number;
+ label: string;
+ progressBarColor: string;
+ textColor: string;
+}
+export const SUBJECT_COLORS = {
+ Maths: "bg-[#107FFC30]",
+ Chemistry: "bg-[#72EFDD4A]",
+ Physics: "bg-[#A36AF53D]",
+};
+
+export const chatPageTabs = [
+ // {
+ // title: "chat",
+ // id: "chat",
+ // desktopView: true,
+ // },
+ {
+ title: "meetings",
+ id: "meetings",
+ desktopView: true,
+ },
+ {
+ title: "request meeting",
+ id: "requestMeeting",
+ desktopView: false,
+ },
+];
+
+export const meetingTabs = [
+ {
+ id: "upcoming",
+ label: "upcoming",
+ },
+ {
+ id: "done",
+ label: "done",
+ },
+];
diff --git a/src/helpers/types/index.ts b/src/helpers/types/index.ts
index 620caf5..fd7965c 100644
--- a/src/helpers/types/index.ts
+++ b/src/helpers/types/index.ts
@@ -1,5 +1,5 @@
import React, { SVGProps } from "react";
-
+import { SUBJECT_COLORS } from "../constants";
export type TContainerProps = {
children: React.ReactNode;
className?: string;
@@ -349,3 +349,13 @@ export type PlannerDataProps = {
export type DataProps = {
data: PlannerDataProps;
};
+
+export type Subject = keyof typeof SUBJECT_COLORS;
+
+export type TMeetingsProps = {
+ rescheduled: {
+ isRescheduled: boolean;
+ date: Date;
+ time: string;
+ };
+}
\ No newline at end of file
diff --git a/src/helpers/utils/index.ts b/src/helpers/utils/index.ts
new file mode 100644
index 0000000..6c91001
--- /dev/null
+++ b/src/helpers/utils/index.ts
@@ -0,0 +1,181 @@
+import DOMPurify from "dompurify";
+import { SUBJECT_COLORS } from "../constants";
+import { Subject } from "../types";
+
+const daysOfWeek = [
+ "Sunday",
+ "Monday",
+ "Tuesday",
+ "Wednesday",
+ "Thursday",
+ "Friday",
+ "Saturday",
+];
+const monthsOfYear = [
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "May",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Oct",
+ "Nov",
+ "Dec",
+];
+
+export function getTodaysDay() {
+ const today = new Date();
+ const dayOfWeek = daysOfWeek[today.getDay()];
+
+ return `${dayOfWeek}`;
+}
+
+export function getMonthDate(date: Date): string {
+ const dayOfMonth: string = String(date.getDate()).padStart(2, "0");
+ const month: string = monthsOfYear[date.getMonth()];
+
+ return `${month} ${dayOfMonth}`;
+}
+
+export function getMonthDateForProd(date: Date): string {
+ // Get the time in milliseconds since the epoch (UTC)
+ const utcTime = date.getTime();
+
+ // Define the IST offset in milliseconds (5 hours and 30 minutes)
+ const istOffset = 5.5 * 60 * 60 * 1000;
+
+ // Calculate the IST time in milliseconds
+ const istTime = utcTime + istOffset;
+
+ // Create a new Date object for IST time
+ const istDate = new Date(istTime);
+
+ // Extract the day of the month and the month name in IST
+ const dayOfMonth: string = String(istDate.getUTCDate()).padStart(2, "0");
+ const month: string = monthsOfYear[istDate.getUTCMonth()];
+
+ return `${month} ${dayOfMonth}`;
+}
+
+export function getTodaysFormattedDate() {
+ const today = new Date();
+ const dayOfMonth = String(today.getDate()).padStart(2, "0");
+ const month = monthsOfYear[today.getMonth()];
+ const year = today.getFullYear();
+
+ return `${dayOfMonth} ${month} ${year}`;
+}
+
+export function getFormattedDate(date: Date): string {
+ const dayOfMonth: string = String(date.getDate()).padStart(2, "0");
+ const month: string = monthsOfYear[date.getMonth()];
+ const year: number = date.getFullYear();
+
+ return `${dayOfMonth} ${month} ${year}`;
+}
+
+export function getFormattedDateForProd(date: Date): string {
+ const istOffset = 5 * 60 * 60 * 1000 + 30 * 60 * 1000; // IST is UTC +5:30
+ const istDate = new Date(date.getTime() + istOffset);
+
+ const dayOfMonth: string = String(istDate.getDate()).padStart(2, "0");
+ const month: string = monthsOfYear[istDate.getMonth()];
+ const year: number = istDate.getFullYear();
+
+ return `${dayOfMonth} ${month} ${year}`;
+}
+
+export function convertDateString(inputDate: Date): string {
+ const utcDate = new Date(inputDate);
+
+ // Convert to IST by adding 5 hours and 30 minutes
+ const istDate = new Date(utcDate.getTime() + 5.5 * 60 * 60 * 1000);
+
+ // Format the date
+ const day = istDate.getDate().toString().padStart(2, "0");
+ const month = (istDate.getMonth() + 1).toString().padStart(2, "0"); // Months are 0-indexed
+ const year = istDate.getFullYear();
+
+ // Format the date as DD-MM-YYYY
+ return `${day}-${month}-${year}`;
+}
+
+export function formatDate(dateString: Date): string {
+ const date = new Date(dateString);
+ const day = date.getDate();
+ const month = date.toLocaleString("default", { month: "short" });
+ return `${day} ${month}`;
+}
+
+export function calculateDaysLeft(meetingDate: Date): number {
+ // Get the current date
+ const currentDate = new Date();
+
+ // Calculate the difference in milliseconds
+ const differenceInMs = meetingDate.getTime() - currentDate.getTime();
+
+ // Convert milliseconds to days
+ const daysLeft = Math.ceil(differenceInMs / (1000 * 60 * 60 * 24));
+
+ return daysLeft;
+}
+
+export function capitalizeFirstLetter(
+ sentence: string | undefined
+): string | undefined {
+ if (!sentence) {
+ return sentence;
+ }
+
+ return sentence.charAt(0).toUpperCase() + sentence.slice(1);
+}
+
+export const formatTime = (seconds: number) => {
+ const days = Math.floor(seconds / (24 * 60 * 60))
+ .toString()
+ .padStart(2, "0");
+ const hours = Math.floor((seconds % (24 * 60 * 60)) / (60 * 60))
+ .toString()
+ .padStart(2, "0");
+ const minutes = Math.floor((seconds % (60 * 60)) / 60)
+ .toString()
+ .padStart(2, "0");
+ const secs = (seconds % 60).toString().padStart(2, "0");
+
+ return `${days}d : ${hours}h : ${minutes}m : ${secs}s`;
+};
+
+export const sanitizedHtml = (htmlString: string) => {
+ DOMPurify.sanitize(htmlString);
+ return htmlString;
+};
+
+export const getColorBySubject = (subject: Subject): string => {
+ return SUBJECT_COLORS[subject] || "bg-[#B0BEC5]";
+};
+
+export function isMoodButtonDisabled(lastMoodDate: String) {
+ if (!lastMoodDate) return false;
+
+ const today = new Date();
+ const formattedToday = today.toISOString().split("T")[0];
+
+ return lastMoodDate === formattedToday;
+}
+
+export const loadRazorpayScript = () => {
+ return new Promise((resolve) => {
+ const script = document.createElement("script");
+ script.src = "https://checkout.razorpay.com/v1/checkout.js";
+ script.onload = () => {
+ resolve(true);
+ };
+ script.onerror = () => {
+ resolve(false);
+ };
+ document.body.appendChild(script);
+ });
+};
diff --git a/src/pages/auth/Login.tsx b/src/pages/auth/Login.tsx
index 22b1f5e..b6bdefe 100644
--- a/src/pages/auth/Login.tsx
+++ b/src/pages/auth/Login.tsx
@@ -23,8 +23,6 @@ const Login = () => {
const handleSubmit = async (e: any) => {
e.preventDefault();
setIsLoggingIn(true);
- setIsLoading(true)
- setLoginSuccess(true)
try {
const response = await apiClient.post(`/api/auth/admin/login`, {
@@ -33,17 +31,23 @@ const Login = () => {
});
if (response.status === 200) {
- navigate('/mentors');
-
+ const { token } = response.data;
+ if (token) {
+ localStorage.setItem("token", token);
+ console.log('Token saved:', token);
+ navigate('/');
+ } else {
+ throw new Error('Token not provided in the response');
+ }
}
- } catch (error: any) {
- setError(error);
-
+ } catch (error: any) {
+ setError(error.response?.data?.message || error.message);
} finally {
setIsLoggingIn(false);
setIsLoading(false)
}
};
+
return (
<>
{isLoading ? (
diff --git a/src/pages/root/dashboard/_components/ContinuousRevision.tsx b/src/pages/root/dashboard/_components/ContinuousRevision.tsx
new file mode 100644
index 0000000..d707bbc
--- /dev/null
+++ b/src/pages/root/dashboard/_components/ContinuousRevision.tsx
@@ -0,0 +1,65 @@
+"use client";
+
+// import { ChatIcon, VideoChatIcon, RequestMeetingIcon } from "@/components";
+// import Link from "next/link";
+import Image from "next/image";
+// import { useAppSelector } from "@/redux/hooks";
+import { Button } from "../../../../components/ui/button";
+// import { useState } from "react";
+// import ContinuousRevisionForm from "./ContinuousRevisionForm";
+// import { ISubject } from "@/helpers/types";
+
+const ContinuousRevision = () => {
+ // const [activeSubject, setActiveSubject] = useState(null);
+
+ // const userSubjects = useAppSelector(
+ // (state) => state.user.user?.academic.subjects
+ // );
+
+ // const userStandard = useAppSelector(
+ // (state) => state.user.user?.academic.standard
+ // );
+
+ return (
+
+ {/* {!activeSubject ? ( */}
+ <>
+
+ What did you Learnt New Today?
+
+
+
+
+
+
+
+ {/* {userSubjects?.map((subject) => ( */}
+
+ {/* ))} */}
+
+ >
+ {/* ) : (
+
+ )} */}
+
+ );
+};
+
+export default ContinuousRevision;
diff --git a/src/pages/root/dashboard/_components/ContinuousRevisionForm.tsx b/src/pages/root/dashboard/_components/ContinuousRevisionForm.tsx
new file mode 100644
index 0000000..5313a55
--- /dev/null
+++ b/src/pages/root/dashboard/_components/ContinuousRevisionForm.tsx
@@ -0,0 +1,271 @@
+"use client";
+
+// import { NewTopicLearntSchema } from "@/schemas/newTopicLearntSchema";
+// import { zodResolver } from "@hookform/resolvers/zod";
+// import * as z from "zod";
+// import { useForm } from "react-hook-form";
+import {
+ // Form,
+ FormControl,
+ FormField,
+ FormItem,
+ FormMessage,
+} from "../../../../components/ui/form";
+import {
+ Popover,
+ PopoverContent,
+ PopoverTrigger,
+} from "../../../../components/ui/popover";
+import { Button } from "../../../../components/ui/button";
+import { cn } from "../../../../lib/utils";
+import { Check, ChevronDown, Loader2 } from "lucide-react";
+import {
+ Command,
+ CommandEmpty,
+ CommandGroup,
+ CommandInput,
+ CommandItem,
+ CommandList,
+} from "../../../../components/ui/command";
+import { MultiSelect } from "../../../../components/ui/multi-select";
+import { LeftArrowIcon } from "../../../../components";
+// import {
+// getChapterTopics,
+// getSubjectChapters,
+// } from "@/actions/question_actions";
+// import { toast } from "sonner";
+import { useState } from "react";
+import { subjectChaptersProps } from "../../../../helpers/types";
+// import { saveStudyData } from "@/actions/studyData_actions";
+// import { updatePlanner } from "@/actions/planner_actions";
+
+const ContinuousRevisionForm = ({
+ // activeSubject,
+ // userStandard,
+ setActiveSubject,
+ // userSubjects,
+}: {
+ activeSubject: string;
+ setActiveSubject: (activeSubject: string | null) => void;
+ userStandard: number;
+ // userSubjects: ISubject[];
+}) => {
+ const [activeTabChapters, setActiveTabChapters] = useState<
+ subjectChaptersProps[]
+ >([]);
+ const [topics, setTopics] = useState([]);
+ const [isSubmitting, setIsSubmitting] = useState(false);
+ const [chapterPopoverOpen, setChapterPopoverOpen] = useState(false);
+
+ // const form = useForm>({
+ // resolver: zodResolver(NewTopicLearntSchema),
+ // });
+
+ // const selectedChapter = form.watch("chapterName");
+
+ // const onSubmit = async (data: z.infer) => {
+ // setIsSubmitting(true);
+
+ // const formattedData = {
+ // tag: "continuous_revision",
+ // topics: data.topicNames.map((topic) => ({ name: topic })),
+ // chapter: {
+ // name: data.chapterName,
+ // },
+ // subject: activeSubject,
+ // standard: userStandard,
+ // };
+
+ // try {
+ // const responseData = await saveStudyData(formattedData);
+
+ // await updatePlanner();
+ // toast.success(responseData.message);
+
+ // form.reset({
+ // chapterName: "",
+ // topicNames: [],
+ // });
+ // } catch (error: any) {
+ // toast.error(error?.message);
+ // } finally {
+ // setIsSubmitting(false);
+ // }
+ // };
+
+ // useEffect(() => {
+ // const chapters = async () => {
+ // try {
+ // const data = await getSubjectChapters(activeSubject, userStandard);
+
+ // setActiveTabChapters(data.chapters);
+ // } catch (error: any) {
+ // toast.error("Unable to fetch chapters!", {
+ // description: error.message,
+ // });
+ // }
+ // };
+
+ // chapters();
+ // }, [activeSubject, userStandard]);
+
+ // useEffect(() => {
+ // const topics = async () => {
+ // try {
+ // const data = await getChapterTopics(
+ // activeSubject,
+ // selectedChapter,
+ // userStandard
+ // );
+ // setTopics(data.topics);
+ // } catch (error: any) {
+ // toast.error("Unable to fetch topics!", {
+ // description: error.message,
+ // });
+ // }
+ // };
+
+ // topics();
+ // }, [activeSubject, selectedChapter, userStandard]);
+
+ return (
+
+
+ {/* {userSubjects.map((subject) => ( */}
+
+ {/* ))} */}
+
+ {/*
+ {/* */}
+
+ );
+};
+
+export default ContinuousRevisionForm;
diff --git a/src/pages/root/dashboard/_components/DailyReport.tsx b/src/pages/root/dashboard/_components/DailyReport.tsx
new file mode 100644
index 0000000..387923c
--- /dev/null
+++ b/src/pages/root/dashboard/_components/DailyReport.tsx
@@ -0,0 +1,49 @@
+"use client";
+
+// import { RadialBarChart } from "../../../../components";
+// import { formatDate } from "../../../../helpers/utils";
+// import { useAppSelector } from "@/redux/hooks";
+
+const DailyReport = () => {
+ // const userDetails = useAppSelector((state) => state.user.user?.details);
+ return (
+
+
Daily Report
+
+ {/*
*/}
+
+
+
+
+ Sessions
+
+
+
+ Quizzes
+
+
+
+
+ );
+};
+
+export default DailyReport;
diff --git a/src/pages/root/dashboard/_components/DailyStreakDialogBox.tsx b/src/pages/root/dashboard/_components/DailyStreakDialogBox.tsx
new file mode 100644
index 0000000..7e3e9b8
--- /dev/null
+++ b/src/pages/root/dashboard/_components/DailyStreakDialogBox.tsx
@@ -0,0 +1,173 @@
+"use client";
+
+import { Button } from "../../../../components/ui/button";
+import { cn } from "../../../../lib/utils";
+import { ArrowLeft } from "lucide-react";
+// import { useState } from "react";
+import Modal from "../../../../components/shared/Modal";
+import { Questions } from "../../../../helpers/types/index";
+// import { sanitizedHtml } from "../../../../helpers/utils/index";
+// import { useAppSelector } from "@/redux/hooks";
+
+const DailyStreakDialogBox = ({
+ setOpenQuestionDialogBox,
+ // questions,
+}: {
+ openQuestionDialogBox: boolean;
+ setOpenQuestionDialogBox: (openQuestionDialogBox: boolean) => void;
+ questions: Questions;
+}) => {
+ // const [activeQuestion, setActiveQuestion] = useState(0);
+ // const [attemptedQuestion, setAttemptedQuestion] = useState([]);
+ // const [selectedAnswer, setSelectedAnswer] = useState("");
+ // const [selectedAnswerIndex, setSelectedAnswerIndex] = useState(
+ // null
+ // );
+
+ // const userSubjects = useAppSelector(
+ // (state) => state.user.user?.academic.subjects
+ // );
+ // const [activeTab, setActiveTab] = useState(userSubjects?.[0]?.name);
+
+ // const questionData = questions[activeTab?.toLowerCase()!];
+
+ // if (!questionData) return null;
+
+ // const { question, options } = questionData;
+
+ // const allOptions = options.map((option: Option) => option.name);
+ // const correctOptions = options
+ // .filter((option: Option) => option.tag === "Correct")
+ // .map((option: Option) => option.name);
+
+ // const onAnswerSelect = (answer: string, index: number) => {
+ // setSelectedAnswerIndex(index);
+
+ // setSelectedAnswer(answer);
+
+ // if (!attemptedQuestion.includes(activeQuestion) && !selectedAnswer) {
+ // setAttemptedQuestion((prev) => [...prev, activeQuestion]);
+ // }
+ // };
+
+ // const handleNextQuestion = () => {
+ // setSelectedAnswerIndex(null);
+ // setSelectedAnswer("");
+
+ // const currentIndex = userSubjects?.findIndex(
+ // (subject) => subject.name === activeTab
+ // );
+ // const nextIndex = (currentIndex! + 1) % userSubjects?.length!;
+ // setActiveTab(userSubjects?.[nextIndex].name);
+ // };
+
+ return (
+
+
+
+
setOpenQuestionDialogBox(false)}
+ >
+
+
+
+
+
+
+
+
+ {/* {userSubjects?.map((tab) => ( */}
+
+ {/* ))} */}
+
+
+
+
+
+
+ );
+};
+
+export default DailyStreakDialogBox;
diff --git a/src/pages/root/dashboard/_components/DailyStreakQuestions.tsx b/src/pages/root/dashboard/_components/DailyStreakQuestions.tsx
new file mode 100644
index 0000000..552a365
--- /dev/null
+++ b/src/pages/root/dashboard/_components/DailyStreakQuestions.tsx
@@ -0,0 +1,83 @@
+"use client";
+
+import { Button } from "../../../../components/ui/button";
+import Image from "next/image";
+import React, { useState } from "react";
+import DailyStreakDialogBox from "./DailyStreakDialogBox";
+import { Questions } from "../../../../helpers/types/index";
+// import { getDailyStreakQuestions } from "@/actions/daily_quiz_actions";
+// import { toast } from "sonner";
+import { Loader2 } from "lucide-react";
+
+const DailyStreakQuestions: React.FC = () => {
+ const [openQuestionDialogBox, setOpenQuestionDialogBox] = useState(false);
+ const [questions, setQuestions] = useState({});
+ const [isQuestionLoading, setIsQuestionLoading] = useState(false);
+
+ // const handleBoxClick = async () => {
+ // setIsQuestionLoading(true);
+ // try {
+ // const response = await getDailyStreakQuestions();
+
+ // if (response.success) {
+ // setQuestions(response.questions);
+ // setOpenQuestionDialogBox(true);
+ // } else {
+ // toast.error("Failed to fetch questions:", {
+ // description: response.message,
+ // });
+ // }
+ // } catch (error: any) {
+ // toast.error("Error fetching questions:", {
+ // description: error.message,
+ // });
+ // } finally {
+ // setIsQuestionLoading(false);
+ // }
+ // };
+
+ return (
+ <>
+
+
+
+ Daily Streak Questions
+
+
+ Daily prompts sustain commitment, motivation.
+
+
+
+
+
+
+
+
+
+ {openQuestionDialogBox && (
+
+ )}
+ >
+ );
+};
+
+export default DailyStreakQuestions;
diff --git a/src/pages/root/dashboard/_components/DesktopUI.tsx b/src/pages/root/dashboard/_components/DesktopUI.tsx
new file mode 100644
index 0000000..465570a
--- /dev/null
+++ b/src/pages/root/dashboard/_components/DesktopUI.tsx
@@ -0,0 +1,86 @@
+"use client";
+import { Header } from "../../../../components";
+
+import TodaysPlan from "./TodaysPlan";
+// import ContinuousRevision from "./ContinuousRevision";
+// import SubjectProgress from "./SubjectProgress";
+// import DailyReport from "./DailyReport";
+// import ProgressAnalytics from "./ProgressAnalytics";
+import ProfileBox from "./ProfileBox";
+import PointsBox from "./PointsBox";
+// import TodaysVibe from "./TodaysVibe";
+// import DailyStreakQuestions from "./DailyStreakQuestions";
+// import UpcomingWorkshops from "./UpcomingWorkshops";
+// import { useAppSelector } from "@/redux/hooks";
+// import UpgradeSubscriptionButton from "./UpgradeSubscriptionButton";
+import { Suspense } from "react";
+import Loader from "../../Loader";
+import { TDayProps } from "../../../.././helpers/types";
+// import InitialTodoBox from "./InitailTodoBox";
+
+const DesktopUI = ({ quizTopics}: { quizTopics: TDayProps }) => {
+ // const user = useAppSelector((state) => state.user.user);
+ return (
+
+
+
+
+
+
+ {/* }
+ /> */}
+ {/* */}
+
+
+
+
+
+
+
+ }>
+ { }
+
+
+
+ {/*
+
+
*/}
+
+
+ {/*
+
+ */}
+
+
+
+
+
+
+
+{/*
+
+
+
+
+ */}
+
+
+
+
+ );
+};
+
+export default DesktopUI;
diff --git a/src/pages/root/dashboard/_components/InitailTodoBox.tsx b/src/pages/root/dashboard/_components/InitailTodoBox.tsx
new file mode 100644
index 0000000..e8396bb
--- /dev/null
+++ b/src/pages/root/dashboard/_components/InitailTodoBox.tsx
@@ -0,0 +1,34 @@
+"use client";
+
+import React from "react";
+import Link from "next/link";
+import { Button } from "@/components/ui/button";
+
+const InitialTodoBox = () => {
+ return (
+
+
+
+ Help us create your plan
+
+
+
+ Please provide an update on the topics you’ve completed in class so
+ far. This will help us tailor the sessions to your needs.
+
+
+
+
+
+
+
+
+
+ );
+};
+
+export default InitialTodoBox;
diff --git a/src/pages/root/dashboard/_components/LevelPoints.tsx b/src/pages/root/dashboard/_components/LevelPoints.tsx
new file mode 100644
index 0000000..abb2ce1
--- /dev/null
+++ b/src/pages/root/dashboard/_components/LevelPoints.tsx
@@ -0,0 +1,85 @@
+import { UpArrowIcon } from "@/components";
+import { Progress } from "@/components/ui/progress";
+import { TLevelPointProps } from "@/helpers/types";
+import { cn } from "@/lib/utils";
+
+import { ChevronRight } from "lucide-react";
+import Image from "next/image";
+import React from "react";
+
+const LevelPoints = ({
+ cardBgColor,
+ iconImageSrc,
+ iconAltText,
+ iconShadowColor,
+ chevronBgColor,
+ pointsColor,
+ points,
+ pointsText,
+ progressValue,
+ pointsProgressText,
+ pointsProgressTextColor,
+ progressIndicatorBg,
+ progressIconStroke,
+}: TLevelPointProps) => {
+ return (
+
+
+
+
+
+
+
+
+
+ {points}
+
+
{pointsText}
+
+
+
+ {/* {pointsText !== "Streak" && (
+
+
+
+
+
+ )} */}
+
+ {pointsText === "Streak" && (
+ <>
+
+ Jan12
+ Feb12
+
+ >
+ )}
+
+
+ );
+};
+
+export default LevelPoints;
diff --git a/src/pages/root/dashboard/_components/MobileUI.tsx b/src/pages/root/dashboard/_components/MobileUI.tsx
new file mode 100644
index 0000000..c5749c1
--- /dev/null
+++ b/src/pages/root/dashboard/_components/MobileUI.tsx
@@ -0,0 +1,55 @@
+"use client";
+import { Header } from "@/components";
+import TodaysPlan from "./TodaysPlan";
+import ContinuousRevision from "./ContinuousRevision";
+import DailyReport from "./DailyReport";
+import SubjectProgress from "./SubjectProgress";
+import ProgressAnalytics from "./ProgressAnalytics";
+import UserProfileSheet from "./UserProfileSheet";
+import UpgradeSubscriptionButton from "./UpgradeSubscriptionButton";
+import { Suspense } from "react";
+import Loader from "@/components/shared/Loader";
+import { TDayProps } from "@/helpers/types";
+import InitialTodoBox from "./InitailTodoBox";
+import { useAppSelector } from "@/redux/hooks";
+
+const MobileUI = ({ quizTopics }: { quizTopics: TDayProps }) => {
+ const user = useAppSelector((state) => state.user.user);
+ return (
+
+
+
+
+ }>
+ {/* */}
+ {user && user.planner === false ? : }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+export default MobileUI;
diff --git a/src/pages/root/dashboard/_components/MoodEmojiSelector.tsx b/src/pages/root/dashboard/_components/MoodEmojiSelector.tsx
new file mode 100644
index 0000000..80d5eb2
--- /dev/null
+++ b/src/pages/root/dashboard/_components/MoodEmojiSelector.tsx
@@ -0,0 +1,102 @@
+"use client";
+
+import { useState } from "react";
+import Image from "next/image";
+
+import { cn } from "../../../../lib/utils";
+// import { toast } from "sonner";
+import { moodEmojis } from "../../../../helpers/constants";
+// import { getUser, setTodaysVibe } from "@/actions/user_actions";
+// import { useAppDispatch, useAppSelector } from "@/redux/hooks";
+// import { userData } from "@/redux/slices/userSlice";
+import { Loader2 } from "lucide-react";
+// import { isMoodButtonDisabled } from "../../../../helpers/utils";
+
+const MoodEmojiSelector = () => {
+ // const user = useAppSelector((state) => state.user.user);
+
+ // const userCurrentMood = user?.details?.mood;
+ const today = new Date().toISOString().split("T")[0];
+
+ // const currentDateMoodIndex = userCurrentMood?.findIndex(
+ // (mood) => mood.day === today
+ // );
+
+ // const [currentMood, setCurrentMood] = useState(
+ // userCurrentMood &&
+ // userCurrentMood.length &&
+ // userCurrentMood?.[currentDateMoodIndex!]?.emoji
+ // ? userCurrentMood?.[currentDateMoodIndex!]?.emoji
+ // : "neutral"
+ // );
+
+ const [isCurrentMood, setIsCurrentMood] = useState(false);
+
+ // const dispatch = useAppDispatch();
+
+ // const handleChangeMood = async (mood: string) => {
+ // setIsCurrentMood(true);
+ // try {
+ // setCurrentMood(mood);
+
+ // const response = await setTodaysVibe({
+ // todaysVibe: mood,
+ // });
+
+ // dispatch(
+ // userData({
+ // ...user,
+ // details: {
+ // ...user?.details,
+ // mood: [...(user?.details?.mood || []), { day: today, emoji: mood }],
+ // },
+ // })
+ // );
+ // toast.success(response.message);
+ // // setIsTodaysMoodSet(true);
+ // } catch (error: any) {
+ // setCurrentMood(currentMood);
+ // toast.error("Saving your current mood failed!", {
+ // description: error.message,
+ // });
+ // } finally {
+ // setIsCurrentMood(false);
+ // }
+ // };
+
+ // const isDisabled = isMoodButtonDisabled(
+ // userCurrentMood?.[currentDateMoodIndex!]?.day!
+ // );
+
+ return (
+
+
+
+ {moodEmojis.map((emoji) => (
+
handleChangeMood(emoji.mood)}
+ className={cn(
+ "cursor-pointer transition-all ease-in duration-200",
+ // currentMood === emoji.mood ? "grayscale-0" : "grayscale",
+ // isCurrentMood && "pointer-events-none opacity-90",
+ // isDisabled && "pointer-events-none opacity-90"
+ )}
+ />
+ ))}
+
+
+
+
+ {isCurrentMood && (
+
+ )}
+
+ );
+};
+
+export default MoodEmojiSelector;
diff --git a/src/pages/root/dashboard/_components/PointsBox.tsx b/src/pages/root/dashboard/_components/PointsBox.tsx
new file mode 100644
index 0000000..63d3d90
--- /dev/null
+++ b/src/pages/root/dashboard/_components/PointsBox.tsx
@@ -0,0 +1,78 @@
+"use client";
+
+// import { useAppSelector } from "@/redux/hooks";
+import LevelPoints from "./LevelPoints";
+
+const PointsBox = () => {
+ // const userDetails = useAppSelector((state) => state.user.user?.details);
+
+ return (
+
+
+
+
+
+ );
+};
+
+export default PointsBox;
diff --git a/src/pages/root/dashboard/_components/ProfileBox.tsx b/src/pages/root/dashboard/_components/ProfileBox.tsx
new file mode 100644
index 0000000..2cf58c3
--- /dev/null
+++ b/src/pages/root/dashboard/_components/ProfileBox.tsx
@@ -0,0 +1,67 @@
+"use client";
+
+import { Avatar, AvatarFallback, AvatarImage } from "../../../../components/ui/avatar";
+import { Button } from "../../../../components/ui/button";
+
+// import { useAppSelector } from "@/redux/hooks";
+
+import Link from "next/link";
+
+const ProfileBox = () => {
+ // const user = useAppSelector((state) => state.user?.user);
+
+ return (
+
+
+
+
+
+ {/* {user?.firstname?.[0]} */}
+
+ {/* {user?.lastname ? user.lastname?.[0] : ""} */}
+
+
+
+
+
+ {/* Hello, {user?.firstname}{" "}
+ {user?.lastname} */}
+
+
+
+
+
+
+
+
+
+
+
+ Embrace the course as a catalyst for personal growth and empowerment,
+ propelling you towards success with unwavering determination.
+
+
+
+
+
+
+
+
+
+ );
+};
+
+export default ProfileBox;
diff --git a/src/pages/root/dashboard/_components/ProgressAnalytics.tsx b/src/pages/root/dashboard/_components/ProgressAnalytics.tsx
new file mode 100644
index 0000000..bce75b6
--- /dev/null
+++ b/src/pages/root/dashboard/_components/ProgressAnalytics.tsx
@@ -0,0 +1,79 @@
+"use client";
+
+import { useState } from "react";
+import {
+ // MonthlyReportChart,
+ // BarChart,
+ // OverallReportChart,
+ TabContent,
+ TabNavItem,
+} from "../../../../components";
+// import { useAppSelector } from "@/redux/hooks";
+
+const progressAnalyticsMenus = [
+ {
+ id: "weekly",
+ title: "Weekly",
+ },
+ {
+ id: "monthly",
+ title: "Monthly",
+ },
+ {
+ id: "overall",
+ title: "Overall",
+ },
+];
+
+const ProgressAnalytics = () => {
+ const [activeTab, setActiveTab] = useState("weekly");
+
+ // const weeklyReportData = useAppSelector((state) => state.weeklyReport.report);
+ // const monthlyReportData = useAppSelector(
+ // (state) => state.monthlyReport.report
+ // );
+ // const overallReportData = useAppSelector(
+ // (state) => state.overallReport.report
+ // );
+
+ return (
+
+
+
Progress Analytics
+
+ {progressAnalyticsMenus.map((tab) => (
+
+ ))}
+
+
+
+
+
+
+ {/* */}
+
+
+
+
+ {/* */}
+
+
+
+
+ {/* */}
+
+
+
+
+ );
+};
+
+export default ProgressAnalytics;
diff --git a/src/pages/root/dashboard/_components/QuestionDialogBox.tsx b/src/pages/root/dashboard/_components/QuestionDialogBox.tsx
new file mode 100644
index 0000000..b2ff608
--- /dev/null
+++ b/src/pages/root/dashboard/_components/QuestionDialogBox.tsx
@@ -0,0 +1,294 @@
+"use client";
+
+import { Button } from "@/components/ui/button";
+import { Progress } from "@/components/ui/progress";
+
+import { cn } from "@/lib/utils";
+
+import { TQuizAnswerProps, TQuizQuestionProps } from "@/helpers/types";
+
+import { ArrowLeft, Check, Loader2, X } from "lucide-react";
+import React, { useState } from "react";
+import { MotionDiv } from "@/components/shared/MotionDiv";
+import Modal from "@/components/shared/Modal";
+
+import { sanitizedHtml } from "@/helpers/utils";
+import { toast } from "sonner";
+import { saveDailyQuiz } from "@/actions/daily_quiz_actions";
+import { getUser } from "@/actions/user_actions";
+import { useAppDispatch } from "@/redux/hooks";
+import { userData } from "@/redux/slices/userSlice";
+import {
+ getMonthlyReport,
+ getOverallReport,
+ getWeeklyReport,
+} from "@/actions/student_report_actions";
+import { weeklyData } from "@/redux/slices/weeklyReportSlice";
+import { monthlyData } from "@/redux/slices/monthlyReportSlice";
+import { overallData } from "@/redux/slices/overallReportSlice";
+
+const QuestionDialogBox = ({
+ setOpenQuestionDialogBox,
+ questions,
+ topic,
+}: {
+ openQuestionDialogBox: boolean;
+ setOpenQuestionDialogBox: (openQuestionDialogBox: boolean) => void;
+ questions: TQuizQuestionProps[];
+ topic: { name: string; _id: string } | null;
+}) => {
+ const [activeQuestion, setActiveQuestion] = useState(0);
+ const [attemptedQuestionIndex, setAttemptedQuestionIndex] = useState<
+ number[]
+ >([]);
+ const [attemptedQuestion, setAttemptedQuestion] = useState<
+ TQuizAnswerProps[]
+ >([]);
+ const [selectedAnswer, setSelectedAnswer] = useState("");
+ const [selectedAnswerIndex, setSelectedAnswerIndex] = useState(
+ null
+ );
+ const [optionSelected, setOptionSelected] = useState(false);
+ const [isSubmitting, setIsSubmitting] = useState(false);
+
+ const dispatch = useAppDispatch();
+
+ const onAnswerSelect = (answer: string, optionTag: string, index: number) => {
+ setSelectedAnswerIndex(index);
+
+ setSelectedAnswer(answer);
+ setOptionSelected(true);
+
+ if (!attemptedQuestionIndex.includes(activeQuestion) && !selectedAnswer) {
+ setAttemptedQuestionIndex((prev) => [...prev, activeQuestion]);
+ }
+
+ const formattedData: TQuizAnswerProps = {
+ question: questions[activeQuestion],
+ studentAnswer: answer,
+ isCorrect: optionTag === "Correct",
+ tag: "daily_quiz",
+ };
+
+ if (!attemptedQuestion.includes(formattedData)) {
+ setAttemptedQuestion((prev) => [...prev, formattedData]);
+ }
+ };
+
+ const handleNextQuestion = () => {
+ setSelectedAnswerIndex(null);
+ setSelectedAnswer("");
+ setOptionSelected(false);
+
+ if (activeQuestion !== questions.length - 1) {
+ setActiveQuestion((prev) => prev + 1);
+ }
+ };
+
+ const onHandleSubmit = async () => {
+ setIsSubmitting(true);
+
+ try {
+ const res = await saveDailyQuiz({
+ topic: { name: topic?.name! },
+ questions: attemptedQuestion,
+ });
+
+ if (res.success) {
+ const userInfo = getUser();
+ const weeklyReportInfo = getWeeklyReport();
+ const monthlyReportInfo = getMonthlyReport();
+ const overallReportInfo = getOverallReport();
+
+ const [user, weeklyReport, monthlyReport, overallReport] =
+ await Promise.all([
+ userInfo,
+ weeklyReportInfo,
+ monthlyReportInfo,
+ overallReportInfo,
+ ]);
+
+ dispatch(userData(user.user));
+ dispatch(weeklyData(weeklyReport.weeklyReport));
+ dispatch(monthlyData(monthlyReport.monthlyReport));
+ dispatch(overallData(overallReport.overallReport));
+ toast.success(res.message);
+
+ setOpenQuestionDialogBox(false);
+ } else {
+ toast.error(res.message);
+ }
+ } catch (error: any) {
+ toast.error(error.message);
+ } finally {
+ setIsSubmitting(false);
+ }
+ };
+
+ return (
+
+ {questions && questions.length > 0 && questions[activeQuestion] ? (
+ <>
+
+
setOpenQuestionDialogBox(false)}
+ >
+
+
+
+
+
+
+ {attemptedQuestionIndex.length}/{questions.length}
+
+
+
+
+
+
+
+
+
+ Quiz on {topic?.name}
+
+
+
+
+ {questions.map((ques, index) => (
+ - {
+ setSelectedAnswerIndex(null);
+ setSelectedAnswer("");
+ setOptionSelected(false);
+ setActiveQuestion(index);
+ }}
+ >
+ Q{index + 1}
+ {activeQuestion === index && (
+
+ )}
+
+ ))}
+
+
+
+
+
+ {activeQuestion + 1}.
+
+
+
+
+
+
+
+
+
+
+ >
+ ) : (
+
+
+ No questions yet!
+
+
+
+ )}
+
+ );
+};
+
+export default QuestionDialogBox;
diff --git a/src/pages/root/dashboard/_components/SubjectProgress.tsx b/src/pages/root/dashboard/_components/SubjectProgress.tsx
new file mode 100644
index 0000000..5942b08
--- /dev/null
+++ b/src/pages/root/dashboard/_components/SubjectProgress.tsx
@@ -0,0 +1,101 @@
+"use client";
+
+import { useState } from "react";
+import { TabContent, TabNavItem } from "../../../../components";
+// import { useAppSelector } from "@/redux/hooks";
+
+const SubjectProgress = () => {
+ // const userSubjects = useAppSelector(
+ // (state) => state.user.user?.academic?.subjects
+ // );
+ // const [activeTab, setActiveTab] = useState(userSubjects?.[0]?.name);
+
+ // const subject = userSubjects?.filter(
+ // (subject) => subject.name === activeTab
+ // )[0];
+
+ return (
+
+
+
Subject Progress
+
+ {/* {userSubjects?.map((tab, i) => ( */}
+ {/* */}
+ {/* ))} */}
+
+
+
+ {/*
*/}
+
+
+ {/* */}
+
+
+
+ {/* */}
+
+
+ {/* */}
+
+ {/*
+
+
+
+
+
+ */}
+
+
+ );
+};
+
+export default SubjectProgress;
diff --git a/src/pages/root/dashboard/_components/TabletUI.tsx b/src/pages/root/dashboard/_components/TabletUI.tsx
new file mode 100644
index 0000000..7d3a7e2
--- /dev/null
+++ b/src/pages/root/dashboard/_components/TabletUI.tsx
@@ -0,0 +1,73 @@
+"use client";
+import { Header } from "@/components";
+import TodaysPlan from "./TodaysPlan";
+import ContinuousRevision from "./ContinuousRevision";
+import SubjectProgress from "./SubjectProgress";
+import ProfileBox from "./ProfileBox";
+import PointsBox from "./PointsBox";
+import DailyStreakQuestions from "./DailyStreakQuestions";
+import TodaysVibe from "./TodaysVibe";
+import UpcomingWorkshops from "./UpcomingWorkshops";
+import DailyReport from "./DailyReport";
+import ProgressAnalytics from "./ProgressAnalytics";
+import UpgradeSubscriptionButton from "./UpgradeSubscriptionButton";
+import { Suspense } from "react";
+import Loader from "@/components/shared/Loader";
+import { TDayProps } from "@/helpers/types";
+import { useAppSelector } from "@/redux/hooks";
+import InitialTodoBox from "./InitailTodoBox";
+
+const TabletUI = ({ quizTopics }: { quizTopics: TDayProps }) => {
+ const user = useAppSelector((state) => state.user.user);
+ return (
+
+
+
+
+
+
+
+
+
+
+
+ }>
+ {/* */}
+ {user && user.planner === false ? : }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+export default TabletUI;
diff --git a/src/pages/root/dashboard/_components/ToDoListButton.tsx b/src/pages/root/dashboard/_components/ToDoListButton.tsx
new file mode 100644
index 0000000..72fb20a
--- /dev/null
+++ b/src/pages/root/dashboard/_components/ToDoListButton.tsx
@@ -0,0 +1,86 @@
+import { TRevisionProps } from "@/helpers/types";
+import { cn } from "@/lib/utils";
+import { Check } from "lucide-react";
+
+const ToDoListButton = ({
+ topic,
+ setTopic,
+ setOpenQuestionDialogBox,
+ completedTopics,
+ incompleteTopics,
+}: {
+ topic: TRevisionProps;
+ completedTopics: any[];
+ incompleteTopics: any[];
+ setOpenQuestionDialogBox: (openQuestionDialogBox: boolean) => void;
+ setTopic: (topic: { name: string; _id: string } | null) => void;
+}) => {
+ const handleCheckboxClick = (topic: string, topicId: string) => {
+ setTopic({ name: topic, _id: topicId });
+ setOpenQuestionDialogBox(true);
+ };
+ return (
+
+
handleCheckboxClick(topic.topic.name, topic._id)}
+ >
+ 0 &&
+ completedTopics.includes(topic.topic.name) &&
+ "bg-[#0FD679]/80 border-none",
+ incompleteTopics &&
+ incompleteTopics.length > 0 &&
+ incompleteTopics.includes(topic.topic.name) &&
+ "bg-[#ff2e2e]/80 border-none"
+ )}
+ >
+ {completedTopics &&
+ completedTopics.length > 0 &&
+ completedTopics.includes(topic.topic.name) && (
+
+ )}
+
+ {incompleteTopics &&
+ incompleteTopics.length > 0 &&
+ incompleteTopics.includes(topic.topic.name) && (
+ !
+ )}
+
+
+
+
+ {completedTopics &&
+ completedTopics.length > 0 &&
+ completedTopics.includes(topic.topic.name) && (
+
+ )}
+ {incompleteTopics &&
+ incompleteTopics.length > 0 &&
+ incompleteTopics.includes(topic.topic.name) && (
+
+ )}
+
+ );
+};
+
+export default ToDoListButton;
diff --git a/src/pages/root/dashboard/_components/TodaysPlan.tsx b/src/pages/root/dashboard/_components/TodaysPlan.tsx
new file mode 100644
index 0000000..b454ddb
--- /dev/null
+++ b/src/pages/root/dashboard/_components/TodaysPlan.tsx
@@ -0,0 +1,133 @@
+"use client";
+
+import { useEffect, useState } from "react";
+import { getTodaysDay, getTodaysFormattedDate } from "../../../../helpers/utils";
+import { TDayProps } from "../../../../helpers/types";
+// import QuestionDialogBox from "./QuestionDialogBox";
+// import Loader from "../../../../components/shared/Loader";
+// import ToDoListButton from "./ToDoListButton";
+import Player from "lottie-react";
+import loginAnimation from "../../../../assets/todo_pending_animation.json";
+
+const TodaysPlan = ({ quizData }: { quizData: TDayProps | undefined }) => {
+ // const [openQuestionDialogBox, setOpenQuestionDialogBox] = useState(false);
+ // const [topic, setTopic] = useState<{ name: string; _id: string } | null>(null);
+ const [hasTopics, setHasTopics] = useState(false);
+ useEffect(() => {
+ if (quizData) {
+ const hasTopicsData =
+ quizData.backRevisionTopics.length > 0
+ // quizData.continuousRevisionTopics.length > 0;
+ setHasTopics(hasTopicsData);
+ }
+ console.log('quizData:', quizData);
+ console.log('hasTopics:', hasTopics);
+ }, [quizData, hasTopics]);
+
+ if (!quizData) {
+ return (
+
+
+
+ Please hold on...
+
+
+ While your plan is being generated, your itinerary will be ready shortly.
+
+
+
+
+
+
+ );
+ }
+
+ // const hasTopics =
+ // quizData.backRevisionTopics.length > 0 ||
+ // quizData.continuousRevisionTopics.length > 0;
+
+ return (
+ <>
+ {/* {hasTopics ? ( */}
+ <>
+
+
+
Todo list
+
+ {getTodaysDay()} {getTodaysFormattedDate()}
+
+
+
+
+
+
+ {/* {quizData.backRevisionTopics.map((topicItem) => (
+
+ ))}
+ {/* {quizData.continuousRevisionTopics.map((topicItem) => ( */}
+ {/*
+ // ))} */}
+
+
+ >
+ {/* ) : ( */}
+ //
+
+
+
+ Please hold on...
+
+
+ While your plan is being generated, your itinerary will be ready shortly.
+
+
+
+ //
+ {/* )} */}
+
+ {/* {openQuestionDialogBox && topic && (
+ }>
+
+
+ )} */}
+ >
+ );
+};
+
+export default TodaysPlan;
diff --git a/src/pages/root/dashboard/_components/TodaysVibe.tsx b/src/pages/root/dashboard/_components/TodaysVibe.tsx
new file mode 100644
index 0000000..7d1a7df
--- /dev/null
+++ b/src/pages/root/dashboard/_components/TodaysVibe.tsx
@@ -0,0 +1,17 @@
+import React from "react";
+import MoodEmojiSelector from "./MoodEmojiSelector";
+
+const TodaysVibe = () => {
+ return (
+
+
Today's Vibes
+
+ Sessions and quizzes were insightful and engaging ?
+
+
+
+
+ );
+};
+
+export default TodaysVibe;
diff --git a/src/pages/root/dashboard/_components/TrialPeriodTimer.tsx b/src/pages/root/dashboard/_components/TrialPeriodTimer.tsx
new file mode 100644
index 0000000..4adfbc7
--- /dev/null
+++ b/src/pages/root/dashboard/_components/TrialPeriodTimer.tsx
@@ -0,0 +1,62 @@
+"use client";
+
+import { formatTime } from "../../../../helpers/utils";
+// import { useAppSelector } from "@/redux/hooks";
+import { useRouter } from "next/navigation";
+import { useEffect, useState } from "react";
+
+const TrialPeriodTimer = () => {
+ const [timeLeft, setTimeLeft] = useState(null);
+
+ const router = useRouter();
+
+ // const subscriptionStatus = useAppSelector(
+ // (state) => state.user.user?.subscription?.status
+ // );
+ // const freeTrialStatus = useAppSelector(
+ // (state) => state.user.user?.freeTrial.active
+ // );
+ // const freeTrialDeactivationDate = useAppSelector(
+ // (state) => state.user.user?.freeTrial?.dateOfDeactivation
+ // );
+
+ // useEffect(() => {
+ // const checkTrialStatus = () => {
+ // const trialEndDate = new Date(freeTrialDeactivationDate!);
+ // const now = new Date();
+
+ // // If the subscription is active, do nothing (user is subscribed)
+ // if (subscriptionStatus === "active") {
+ // return;
+ // }
+
+ // // If no active free trial or the free trial has expired, redirect to subscription plans
+ // if (!freeTrialStatus || now >= trialEndDate) {
+ // router.replace("/subscription-plans");
+ // } else {
+ // // Calculate remaining time for the active free trial
+ // const remainingTime = Math.max(
+ // 0,
+ // Math.floor((trialEndDate.getTime() - now.getTime()) / 1000)
+ // );
+ // setTimeLeft(remainingTime);
+ // }
+ // };
+
+ // checkTrialStatus();
+
+ // const timerInterval = setInterval(() => {
+ // checkTrialStatus();
+ // }, 1000);
+
+ // return () => clearInterval(timerInterval);
+ // }, [freeTrialDeactivationDate, freeTrialStatus, router, subscriptionStatus]);
+
+ return (
+
+ {timeLeft !== null ? formatTime(timeLeft) : "Loading..."}
+
+ );
+};
+
+export default TrialPeriodTimer;
diff --git a/src/pages/root/dashboard/_components/UpcomingWorkshops.tsx b/src/pages/root/dashboard/_components/UpcomingWorkshops.tsx
new file mode 100644
index 0000000..6af9add
--- /dev/null
+++ b/src/pages/root/dashboard/_components/UpcomingWorkshops.tsx
@@ -0,0 +1,64 @@
+import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
+import { Ellipsis } from "lucide-react";
+import Image from "next/image";
+import React from "react";
+
+const UpcomingWorkshops = () => {
+ return (
+
+
Upcoming Workshops
+
+
+
+
+
+
+
+ Study On Ocular Potential
+
+
+ It tells about Visual function
+
+
+ Meeting at 10AM, 27Feb 2024
+
+
+
+
+ - By Doris Wilson
+
+ {/*
+
+
*/}
+
+
+
+ LA
+
+
+
+
+
+
+ );
+};
+
+export default UpcomingWorkshops;
diff --git a/src/pages/root/dashboard/_components/UserProfileSheet.tsx b/src/pages/root/dashboard/_components/UserProfileSheet.tsx
new file mode 100644
index 0000000..2c5b57b
--- /dev/null
+++ b/src/pages/root/dashboard/_components/UserProfileSheet.tsx
@@ -0,0 +1,55 @@
+"use client";
+
+import {
+ Sheet,
+ SheetContent,
+ SheetHeader,
+ SheetTrigger,
+} from "@/components/ui/sheet";
+import { ArrowLeft } from "lucide-react";
+import ProfileBox from "./ProfileBox";
+import PointsBox from "./PointsBox";
+import TodaysVibe from "./TodaysVibe";
+import DailyStreakQuestions from "./DailyStreakQuestions";
+import UpcomingWorkshops from "./UpcomingWorkshops";
+import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
+
+import { useAppSelector } from "@/redux/hooks";
+
+const UserProfileSheet = () => {
+ const user = useAppSelector((state) => state.user.user);
+ return (
+
+
+
+
+
+ {user?.firstname?.[0]}
+
+ {user?.lastname ? user.lastname?.[0] : ""}
+
+
+
+
+ }
+ sheetCloseClassName="left-4"
+ >
+
+ Profile
+
+
+
+
+
+
+
+
+ );
+};
+
+export default UserProfileSheet;
diff --git a/src/pages/root/dashboard/_components/_skeletons/ToDoSkeleton.tsx b/src/pages/root/dashboard/_components/_skeletons/ToDoSkeleton.tsx
new file mode 100644
index 0000000..8eb1e6c
--- /dev/null
+++ b/src/pages/root/dashboard/_components/_skeletons/ToDoSkeleton.tsx
@@ -0,0 +1,23 @@
+import { Skeleton } from "@/components/ui/skeleton";
+import React from "react";
+
+const ToDoSkeleton = () => {
+ return (
+
+
+
+
+
+
+ {Array.from({ length: 5 }).map((_, i) => (
+
+
+
+
+ ))}
+
+
+ );
+};
+
+export default ToDoSkeleton;
diff --git a/src/pages/root/dashboard/page.tsx b/src/pages/root/dashboard/page.tsx
new file mode 100644
index 0000000..509b116
--- /dev/null
+++ b/src/pages/root/dashboard/page.tsx
@@ -0,0 +1,29 @@
+"use client";
+import { getPlanner } from "../../../actions/planner_actions";
+import DesktopUI from "./_components/DesktopUI";
+// import MobileUI from "./_components/MobileUI";
+// import TabletUI from "./_components/TabletUI";
+import { DataProps } from "../../../helpers/types";
+import { getFormattedDate, getFormattedDateForProd } from "../../../helpers/utils";
+
+const Dashboard = async () => {
+ const { data }: DataProps = await getPlanner();
+
+ return (
+
+
+ process.env.NODE_ENV === "development"
+ ? getFormattedDate(new Date(item.date)) ===
+ getFormattedDate(new Date(Date.now()))
+ : getFormattedDateForProd(new Date(item.date)) ===
+ getFormattedDateForProd(new Date(Date.now()))
+ )[0]
+ }
+ />
+
+ );
+};
+
+export default Dashboard;
diff --git a/src/pages/root/layout.tsx b/src/pages/root/layout.tsx
new file mode 100644
index 0000000..c7288f8
--- /dev/null
+++ b/src/pages/root/layout.tsx
@@ -0,0 +1,34 @@
+"use client";
+import type { Metadata } from "next";
+import Sidebar from "../../components/shared/Sidebar";
+import MobileMenu from "../../components/shared/MobileMenu";
+
+export const metadata: Metadata = {
+ title: "Leadlly",
+ description:
+ "Say goodbye to one-size-fits-all! We tailor study plans and resources to your individual learning style and goals.",
+};
+
+export default function MainLayout({
+ children,
+}: Readonly<{
+ children: React.ReactNode;
+}>) {
+ const meetingsLength = 0; // Set a default value for meetingsLength
+
+ return (
+ <>
+
+
+ {/* Pass the default value */}
+
+
+ {children}
+
+
+
+ {/* Pass the default value */}
+
+ >
+ );
+}
diff --git a/vite.config.ts b/vite.config.ts
index d36c010..a36e829 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -9,4 +9,7 @@ export default defineConfig({
"@": path.resolve(__dirname, "./src"),
},
},
+ define: {
+ 'process.env': {},
+ },
})
\ No newline at end of file