diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..c5d7eef --- /dev/null +++ b/.env.example @@ -0,0 +1,2 @@ +NEXT_PUBLIC_OPENAI_API_KEY=your-api-key-here +# Use this until ChatBox code for openai api streaming is moved to backend \ No newline at end of file diff --git a/.gitignore b/.gitignore index a27ec58..458b3f8 100644 --- a/.gitignore +++ b/.gitignore @@ -32,6 +32,7 @@ yarn-error.log* # env files (can opt-in for committing if needed) .env* +!.env.example # vercel .vercel diff --git a/components.json b/components.json index 24be433..05743b4 100644 --- a/components.json +++ b/components.json @@ -5,13 +5,16 @@ "tsx": true, "tailwind": { "config": "tailwind.config.js", - "css": "src/app/globals.css", + "css": "src/app/(HomePage)/globals.css", "baseColor": "neutral", "cssVariables": true, "prefix": "" }, "aliases": { "components": "@/components", - "utils": "@/lib/utils" + "utils": "@/lib/utils", + "ui": "@/components/ui", + "lib": "@/lib", + "hooks": "@/hooks" } } diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000..82c2e20 --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,28 @@ +import js from '@eslint/js'; +import globals from 'globals'; +import reactHooks from 'eslint-plugin-react-hooks'; +import reactRefresh from 'eslint-plugin-react-refresh'; +import tseslint from 'typescript-eslint'; + +export default tseslint.config( + { ignores: ['dist'] }, + { + extends: [js.configs.recommended, ...tseslint.configs.recommended], + files: ['**/*.{ts,tsx}'], + languageOptions: { + ecmaVersion: 2020, + globals: globals.browser, + }, + plugins: { + 'react-hooks': reactHooks, + 'react-refresh': reactRefresh, + }, + rules: { + ...reactHooks.configs.recommended.rules, + 'react-refresh/only-export-components': [ + 'warn', + { allowConstantExport: true }, + ], + }, + } +); diff --git a/package-lock.json b/package-lock.json index 6e18c31..44b2a32 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,8 +12,10 @@ "@fontsource/poppins": "^5.2.5", "@fontsource/public-sans": "^5.2.5", "@headlessui/react": "^2.2.1", + "@heroicons/react": "^2.2.0", "@langchain/core": "^0.3.44", "@langchain/openai": "^0.5.5", + "@material-tailwind/react": "^2.1.10", "@radix-ui/react-dialog": "^1.1.6", "@radix-ui/react-icons": "^1.3.2", "@radix-ui/react-slot": "^1.1.2", @@ -21,6 +23,7 @@ "@react-three/fiber": "^8.16.0", "@types/d3-force": "^3.0.10", "@vercel/analytics": "^1.5.0", + "axios": "^1.8.4", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "d3": "^7.9.0", @@ -61,7 +64,7 @@ "@types/d3-selection": "^3.0.11", "@types/d3-zoom": "^3.0.8", "@types/node": "^20", - "@types/react": "^18.3.5", + "@types/react": "^18.2.42", "@types/react-dom": "^18.3.0", "@types/react-slick": "^0.23.13", "@types/react-virtualized-auto-sizer": "^1.0.4", @@ -104,38 +107,22 @@ "integrity": "sha512-gAmrUZSGtKc3AiBL71iNWxDsyUC5uMaKKGdvzYsBoTW/xi42JQHl7eKV2OYzCUqvc+D2RCcf7EXY2iCyFIk6og==", "license": "MIT" }, - "node_modules/@emnapi/core": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.4.0.tgz", - "integrity": "sha512-H+N/FqT07NmLmt6OFFtDfwe8PNygprzBikrEMyQfgqSmT0vzE515Pz7R8izwB9q/zsH/MA64AKoul3sA6/CzVg==", - "dev": true, + "node_modules/@emotion/is-prop-valid": { + "version": "0.8.8", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz", + "integrity": "sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==", "license": "MIT", "optional": true, "dependencies": { - "@emnapi/wasi-threads": "1.0.1", - "tslib": "^2.4.0" + "@emotion/memoize": "0.7.4" } }, - "node_modules/@emnapi/runtime": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.0.tgz", - "integrity": "sha512-64WYIf4UYcdLnbKn/umDlNjQDSS8AgZrI/R9+x5ilkUVFxXcA1Ebl+gQLc/6mERA4407Xof0R7wEyEuj091CVw==", - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@emnapi/wasi-threads": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.0.1.tgz", - "integrity": "sha512-iIBu7mwkq4UQGeMEM8bLwNK962nXdhodeScX4slfQnRhEMMzvYivHhutCIk8uojvmASXXPC2WNEjwxFWk72Oqw==", - "dev": true, + "node_modules/@emotion/memoize": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz", + "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==", "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } + "optional": true }, "node_modules/@eslint-community/eslint-utils": { "version": "4.5.1", @@ -387,6 +374,15 @@ "react-dom": "^18 || ^19 || ^19.0.0-rc" } }, + "node_modules/@heroicons/react": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@heroicons/react/-/react-2.2.0.tgz", + "integrity": "sha512-LMcepvRaS9LYHJGsF0zzmgKCUim/X3N/DQKc4jepAXJ7l8QxJ1PmxJzqplF2Z3FE4PqBAIGyJAQ/w4B5dsqbtQ==", + "license": "MIT", + "peerDependencies": { + "react": ">= 16 || ^19.0.0-rc" + } + }, "node_modules/@humanfs/core": { "version": "0.19.1", "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", @@ -453,364 +449,6 @@ "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@img/sharp-darwin-arm64": { - "version": "0.34.1", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.1.tgz", - "integrity": "sha512-pn44xgBtgpEbZsu+lWf2KNb6OAf70X68k+yk69Ic2Xz11zHR/w24/U49XT7AeRwJ0Px+mhALhU5LPci1Aymk7A==", - "cpu": [ - "arm64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-darwin-arm64": "1.1.0" - } - }, - "node_modules/@img/sharp-darwin-x64": { - "version": "0.34.1", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.1.tgz", - "integrity": "sha512-VfuYgG2r8BpYiOUN+BfYeFo69nP/MIwAtSJ7/Zpxc5QF3KS22z8Pvg3FkrSFJBPNQ7mmcUcYQFBmEQp7eu1F8Q==", - "cpu": [ - "x64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-darwin-x64": "1.1.0" - } - }, - "node_modules/@img/sharp-libvips-darwin-arm64": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.1.0.tgz", - "integrity": "sha512-HZ/JUmPwrJSoM4DIQPv/BfNh9yrOA8tlBbqbLz4JZ5uew2+o22Ik+tHQJcih7QJuSa0zo5coHTfD5J8inqj9DA==", - "cpu": [ - "arm64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "darwin" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-darwin-x64": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.1.0.tgz", - "integrity": "sha512-Xzc2ToEmHN+hfvsl9wja0RlnXEgpKNmftriQp6XzY/RaSfwD9th+MSh0WQKzUreLKKINb3afirxW7A0fz2YWuQ==", - "cpu": [ - "x64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "darwin" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-arm": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.1.0.tgz", - "integrity": "sha512-s8BAd0lwUIvYCJyRdFqvsj+BJIpDBSxs6ivrOPm/R7piTs5UIwY5OjXrP2bqXC9/moGsyRa37eYWYCOGVXxVrA==", - "cpu": [ - "arm" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-arm64": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.1.0.tgz", - "integrity": "sha512-IVfGJa7gjChDET1dK9SekxFFdflarnUB8PwW8aGwEoF3oAsSDuNUTYS+SKDOyOJxQyDC1aPFMuRYLoDInyV9Ew==", - "cpu": [ - "arm64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-ppc64": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.1.0.tgz", - "integrity": "sha512-tiXxFZFbhnkWE2LA8oQj7KYR+bWBkiV2nilRldT7bqoEZ4HiDOcePr9wVDAZPi/Id5fT1oY9iGnDq20cwUz8lQ==", - "cpu": [ - "ppc64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-s390x": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.1.0.tgz", - "integrity": "sha512-xukSwvhguw7COyzvmjydRb3x/09+21HykyapcZchiCUkTThEQEOMtBj9UhkaBRLuBrgLFzQ2wbxdeCCJW/jgJA==", - "cpu": [ - "s390x" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-x64": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.1.0.tgz", - "integrity": "sha512-yRj2+reB8iMg9W5sULM3S74jVS7zqSzHG3Ol/twnAAkAhnGQnpjj6e4ayUz7V+FpKypwgs82xbRdYtchTTUB+Q==", - "cpu": [ - "x64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linuxmusl-arm64": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.1.0.tgz", - "integrity": "sha512-jYZdG+whg0MDK+q2COKbYidaqW/WTz0cc1E+tMAusiDygrM4ypmSCjOJPmFTvHHJ8j/6cAGyeDWZOsK06tP33w==", - "cpu": [ - "arm64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linuxmusl-x64": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.1.0.tgz", - "integrity": "sha512-wK7SBdwrAiycjXdkPnGCPLjYb9lD4l6Ze2gSdAGVZrEL05AOUJESWU2lhlC+Ffn5/G+VKuSm6zzbQSzFX/P65A==", - "cpu": [ - "x64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-linux-arm": { - "version": "0.34.1", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.1.tgz", - "integrity": "sha512-anKiszvACti2sGy9CirTlNyk7BjjZPiML1jt2ZkTdcvpLU1YH6CXwRAZCA2UmRXnhiIftXQ7+Oh62Ji25W72jA==", - "cpu": [ - "arm" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-arm": "1.1.0" - } - }, - "node_modules/@img/sharp-linux-arm64": { - "version": "0.34.1", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.1.tgz", - "integrity": "sha512-kX2c+vbvaXC6vly1RDf/IWNXxrlxLNpBVWkdpRq5Ka7OOKj6nr66etKy2IENf6FtOgklkg9ZdGpEu9kwdlcwOQ==", - "cpu": [ - "arm64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-arm64": "1.1.0" - } - }, - "node_modules/@img/sharp-linux-s390x": { - "version": "0.34.1", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.1.tgz", - "integrity": "sha512-7s0KX2tI9mZI2buRipKIw2X1ufdTeaRgwmRabt5bi9chYfhur+/C1OXg3TKg/eag1W+6CCWLVmSauV1owmRPxA==", - "cpu": [ - "s390x" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-s390x": "1.1.0" - } - }, - "node_modules/@img/sharp-linux-x64": { - "version": "0.34.1", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.1.tgz", - "integrity": "sha512-wExv7SH9nmoBW3Wr2gvQopX1k8q2g5V5Iag8Zk6AVENsjwd+3adjwxtp3Dcu2QhOXr8W9NusBU6XcQUohBZ5MA==", - "cpu": [ - "x64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-x64": "1.1.0" - } - }, - "node_modules/@img/sharp-linuxmusl-arm64": { - "version": "0.34.1", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.1.tgz", - "integrity": "sha512-DfvyxzHxw4WGdPiTF0SOHnm11Xv4aQexvqhRDAoD00MzHekAj9a/jADXeXYCDFH/DzYruwHbXU7uz+H+nWmSOQ==", - "cpu": [ - "arm64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-arm64": "1.1.0" - } - }, - "node_modules/@img/sharp-linuxmusl-x64": { - "version": "0.34.1", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.1.tgz", - "integrity": "sha512-pax/kTR407vNb9qaSIiWVnQplPcGU8LRIJpDT5o8PdAx5aAA7AS3X9PS8Isw1/WfqgQorPotjrZL3Pqh6C5EBg==", - "cpu": [ - "x64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-x64": "1.1.0" - } - }, - "node_modules/@img/sharp-wasm32": { - "version": "0.34.1", - "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.1.tgz", - "integrity": "sha512-YDybQnYrLQfEpzGOQe7OKcyLUCML4YOXl428gOOzBgN6Gw0rv8dpsJ7PqTHxBnXnwXr8S1mYFSLSa727tpz0xg==", - "cpu": [ - "wasm32" - ], - "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", - "optional": true, - "dependencies": { - "@emnapi/runtime": "^1.4.0" - }, - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-win32-ia32": { - "version": "0.34.1", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.1.tgz", - "integrity": "sha512-WKf/NAZITnonBf3U1LfdjoMgNO5JYRSlhovhRhMxXVdvWYveM4kM3L8m35onYIdh75cOMCo1BexgVQcCDzyoWw==", - "cpu": [ - "ia32" - ], - "license": "Apache-2.0 AND LGPL-3.0-or-later", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, "node_modules/@img/sharp-win32-x64": { "version": "0.34.1", "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.1.tgz", @@ -963,6 +601,110 @@ "@langchain/core": ">=0.2.21 <0.4.0" } }, + "node_modules/@material-tailwind/react": { + "version": "2.1.10", + "resolved": "https://registry.npmjs.org/@material-tailwind/react/-/react-2.1.10.tgz", + "integrity": "sha512-xGU/mLDKDBp/qZ8Dp2XR7fKcTpDuFeZEBqoL9Bk/29kakKxNxjUGYSRHEFLsyOFf4VIhU6WGHdIS7tOA3QGJHA==", + "license": "MIT", + "dependencies": { + "@floating-ui/react": "0.19.0", + "classnames": "2.3.2", + "deepmerge": "4.2.2", + "framer-motion": "6.5.1", + "material-ripple-effects": "2.0.1", + "prop-types": "15.8.1", + "react": "18.2.0", + "react-dom": "18.2.0", + "tailwind-merge": "1.8.1" + }, + "peerDependencies": { + "react": "^16 || ^17 || ^18", + "react-dom": "^16 || ^17 || ^18" + } + }, + "node_modules/@material-tailwind/react/node_modules/@floating-ui/react": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.19.0.tgz", + "integrity": "sha512-fgYvN4ksCi5OvmPXkyOT8o5a8PSKHMzPHt+9mR6KYWdF16IAjWRLZPAAziI2sznaWT23drRFrYw64wdvYqqaQw==", + "license": "MIT", + "dependencies": { + "@floating-ui/react-dom": "^1.2.2", + "aria-hidden": "^1.1.3", + "tabbable": "^6.0.1" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@material-tailwind/react/node_modules/@floating-ui/react-dom": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-1.3.0.tgz", + "integrity": "sha512-htwHm67Ji5E/pROEAr7f8IKFShuiCKHwUC/UY4vC3I5jiSvGFAYnSYiZO5MlGmads+QqvUkR9ANHEguGrDv72g==", + "license": "MIT", + "dependencies": { + "@floating-ui/dom": "^1.2.1" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@material-tailwind/react/node_modules/classnames": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz", + "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==", + "license": "MIT" + }, + "node_modules/@material-tailwind/react/node_modules/deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@material-tailwind/react/node_modules/react": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", + "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@material-tailwind/react/node_modules/react-dom": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", + "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.0" + }, + "peerDependencies": { + "react": "^18.2.0" + } + }, + "node_modules/@material-tailwind/react/node_modules/scheduler": { + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/@material-tailwind/react/node_modules/tailwind-merge": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-1.8.1.tgz", + "integrity": "sha512-+fflfPxvHFr81hTJpQ3MIwtqgvefHZFUHFiIHpVIRXvG/nX9+gu2P7JNlFu2bfDMJ+uHhi/pUgzaYacMoXv+Ww==", + "license": "MIT" + }, "node_modules/@mediapipe/tasks-vision": { "version": "0.10.17", "resolved": "https://registry.npmjs.org/@mediapipe/tasks-vision/-/tasks-vision-0.10.17.tgz", @@ -981,17 +723,68 @@ "three": ">= 0.159.0" } }, - "node_modules/@napi-rs/wasm-runtime": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.8.tgz", - "integrity": "sha512-OBlgKdX7gin7OIq4fadsjpg+cp2ZphvAIKucHsNfTdJiqdOmOEwQd/bHi0VwNrcw5xpBJyUw6cK/QilCqy1BSg==", - "dev": true, + "node_modules/@motionone/animation": { + "version": "10.18.0", + "resolved": "https://registry.npmjs.org/@motionone/animation/-/animation-10.18.0.tgz", + "integrity": "sha512-9z2p5GFGCm0gBsZbi8rVMOAJCtw1WqBTIPw3ozk06gDvZInBPIsQcHgYogEJ4yuHJ+akuW8g1SEIOpTOvYs8hw==", + "license": "MIT", + "dependencies": { + "@motionone/easing": "^10.18.0", + "@motionone/types": "^10.17.1", + "@motionone/utils": "^10.18.0", + "tslib": "^2.3.1" + } + }, + "node_modules/@motionone/dom": { + "version": "10.12.0", + "resolved": "https://registry.npmjs.org/@motionone/dom/-/dom-10.12.0.tgz", + "integrity": "sha512-UdPTtLMAktHiqV0atOczNYyDd/d8Cf5fFsd1tua03PqTwwCe/6lwhLSQ8a7TbnQ5SN0gm44N1slBfj+ORIhrqw==", + "license": "MIT", + "dependencies": { + "@motionone/animation": "^10.12.0", + "@motionone/generators": "^10.12.0", + "@motionone/types": "^10.12.0", + "@motionone/utils": "^10.12.0", + "hey-listen": "^1.0.8", + "tslib": "^2.3.1" + } + }, + "node_modules/@motionone/easing": { + "version": "10.18.0", + "resolved": "https://registry.npmjs.org/@motionone/easing/-/easing-10.18.0.tgz", + "integrity": "sha512-VcjByo7XpdLS4o9T8t99JtgxkdMcNWD3yHU/n6CLEz3bkmKDRZyYQ/wmSf6daum8ZXqfUAgFeCZSpJZIMxaCzg==", + "license": "MIT", + "dependencies": { + "@motionone/utils": "^10.18.0", + "tslib": "^2.3.1" + } + }, + "node_modules/@motionone/generators": { + "version": "10.18.0", + "resolved": "https://registry.npmjs.org/@motionone/generators/-/generators-10.18.0.tgz", + "integrity": "sha512-+qfkC2DtkDj4tHPu+AFKVfR/C30O1vYdvsGYaR13W/1cczPrrcjdvYCj0VLFuRMN+lP1xvpNZHCRNM4fBzn1jg==", + "license": "MIT", + "dependencies": { + "@motionone/types": "^10.17.1", + "@motionone/utils": "^10.18.0", + "tslib": "^2.3.1" + } + }, + "node_modules/@motionone/types": { + "version": "10.17.1", + "resolved": "https://registry.npmjs.org/@motionone/types/-/types-10.17.1.tgz", + "integrity": "sha512-KaC4kgiODDz8hswCrS0btrVrzyU2CSQKO7Ps90ibBVSQmjkrt2teqta6/sOG59v7+dPnKMAg13jyqtMKV2yJ7A==", + "license": "MIT" + }, + "node_modules/@motionone/utils": { + "version": "10.18.0", + "resolved": "https://registry.npmjs.org/@motionone/utils/-/utils-10.18.0.tgz", + "integrity": "sha512-3XVF7sgyTSI2KWvTf6uLlBJ5iAgRgmvp3bpuOiQJvInd4nZ19ET8lX5unn30SlmRH7hXbBbH+Gxd0m0klJ3Xtw==", "license": "MIT", - "optional": true, "dependencies": { - "@emnapi/core": "^1.4.0", - "@emnapi/runtime": "^1.4.0", - "@tybys/wasm-util": "^0.9.0" + "@motionone/types": "^10.17.1", + "hey-listen": "^1.0.8", + "tslib": "^2.3.1" } }, "node_modules/@next/env": { @@ -1017,7 +810,6 @@ "cpu": [ "arm64" ], - "license": "MIT", "optional": true, "os": [ "darwin" @@ -1033,7 +825,6 @@ "cpu": [ "x64" ], - "license": "MIT", "optional": true, "os": [ "darwin" @@ -1049,7 +840,6 @@ "cpu": [ "arm64" ], - "license": "MIT", "optional": true, "os": [ "linux" @@ -1065,7 +855,6 @@ "cpu": [ "arm64" ], - "license": "MIT", "optional": true, "os": [ "linux" @@ -1081,7 +870,6 @@ "cpu": [ "x64" ], - "license": "MIT", "optional": true, "os": [ "linux" @@ -1097,7 +885,6 @@ "cpu": [ "x64" ], - "license": "MIT", "optional": true, "os": [ "linux" @@ -1113,7 +900,6 @@ "cpu": [ "arm64" ], - "license": "MIT", "optional": true, "os": [ "win32" @@ -1129,7 +915,6 @@ "cpu": [ "ia32" ], - "license": "MIT", "optional": true, "os": [ "win32" @@ -1900,17 +1685,6 @@ "integrity": "sha512-vJmvvwFxYuGnF2axRtPYocag6Clbb5YS7kLL+SO/TeVFzHqDIWrNKYtcsPMibjDx9O+bu+psAy9NKfWklassUA==", "license": "MIT" }, - "node_modules/@tybys/wasm-util": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.9.0.tgz", - "integrity": "sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, "node_modules/@types/d3": { "version": "7.4.3", "resolved": "https://registry.npmjs.org/@types/d3/-/d3-7.4.3.tgz", @@ -2292,12 +2066,13 @@ "license": "MIT" }, "node_modules/@types/react": { - "version": "18.3.20", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.20.tgz", - "integrity": "sha512-IPaCZN7PShZK/3t6Q87pfTkRm6oLTd4vztyoj+cbHUF1g3FfVb2tFIL79uCRKEfv16AhqDMBywP2VW3KIZUvcg==", + "version": "18.2.42", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.42.tgz", + "integrity": "sha512-c1zEr96MjakLYus/wPnuWDo1/zErfdU9rNsIGmE+NV71nx88FG9Ttgo5dqorXTu/LImX2f63WBP986gJkMPNbA==", "license": "MIT", "dependencies": { "@types/prop-types": "*", + "@types/scheduler": "*", "csstype": "^3.0.2" } }, @@ -2356,6 +2131,12 @@ "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", "license": "MIT" }, + "node_modules/@types/scheduler": { + "version": "0.26.0", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.26.0.tgz", + "integrity": "sha512-WFHp9YUJQ6CKshqoC37iOlHnQSmxNc795UhB26CyBBttrN9svdIrUjl/NjnNmfcwtncN0h/0PPAFWv9ovP8mLA==", + "license": "MIT" + }, "node_modules/@types/stats.js": { "version": "0.17.3", "resolved": "https://registry.npmjs.org/@types/stats.js/-/stats.js-0.17.3.tgz", @@ -2636,205 +2417,6 @@ "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", "license": "ISC" }, - "node_modules/@unrs/resolver-binding-darwin-arm64": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.4.1.tgz", - "integrity": "sha512-8Tv+Bsd0BjGwfEedIyor4inw8atppRxM5BdUnIt+3mAm/QXUm7Dw74CHnXpfZKXkp07EXJGiA8hStqCINAWhdw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@unrs/resolver-binding-darwin-x64": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.4.1.tgz", - "integrity": "sha512-X8c3PhWziEMKAzZz+YAYWfwawi5AEgzy/hmfizAB4C70gMHLKmInJcp1270yYAOs7z07YVFI220pp50z24Jk3A==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@unrs/resolver-binding-freebsd-x64": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.4.1.tgz", - "integrity": "sha512-UUr/nREy1UdtxXQnmLaaTXFGOcGxPwNIzeJdb3KXai3TKtC1UgNOB9s8KOA4TaxOUBR/qVgL5BvBwmUjD5yuVA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.4.1.tgz", - "integrity": "sha512-e3pII53dEeS8inkX6A1ad2UXE0nuoWCqik4kOxaDnls0uJUq0ntdj5d9IYd+bv5TDwf9DSge/xPOvCmRYH+Tsw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.4.1.tgz", - "integrity": "sha512-e/AKKd9gR+HNmVyDEPI/PIz2t0DrA3cyonHNhHVjrkxe8pMCiYiqhtn1+h+yIpHUtUlM6Y1FNIdivFa+r7wrEQ==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-arm64-gnu": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.4.1.tgz", - "integrity": "sha512-vtIu34luF1jRktlHtiwm2mjuE8oJCsFiFr8hT5+tFQdqFKjPhbJXn83LswKsOhy0GxAEevpXDI4xxEwkjuXIPA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-arm64-musl": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.4.1.tgz", - "integrity": "sha512-H3PaOuGyhFXiyJd+09uPhGl4gocmhyi1BRzvsP8Lv5AQO3p3/ZY7WjV4t2NkBksm9tMjf3YbOVHyPWi2eWsNYw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.4.1.tgz", - "integrity": "sha512-4+GmJcaaFntCi1S01YByqp8wLMjV/FyQyHVGm0vedIhL1Vfx7uHkz/sZmKsidRwokBGuxi92GFmSzqT2O8KcNA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-s390x-gnu": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.4.1.tgz", - "integrity": "sha512-6RDQVCmtFYTlhy89D5ixTqo9bTQqFhvNN0Ey1wJs5r+01Dq15gPHRXv2jF2bQATtMrOfYwv+R2ZR9ew1N1N3YQ==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-x64-gnu": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.4.1.tgz", - "integrity": "sha512-XpU9uzIkD86+19NjCXxlVPISMUrVXsXo5htxtuG+uJ59p5JauSRZsIxQxzzfKzkxEjdvANPM/lS1HFoX6A6QeA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-x64-musl": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.4.1.tgz", - "integrity": "sha512-3CDjG/spbTKCSHl66QP2ekHSD+H34i7utuDIM5gzoNBcZ1gTO0Op09Wx5cikXnhORRf9+HyDWzm37vU1PLSM1A==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-wasm32-wasi": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.4.1.tgz", - "integrity": "sha512-50tYhvbCTnuzMn7vmP8IV2UKF7ITo1oihygEYq9wW2DUb/Y+QMqBHJUSCABRngATjZ4shOK6f2+s0gQX6ElENQ==", - "cpu": [ - "wasm32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@napi-rs/wasm-runtime": "^0.2.8" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@unrs/resolver-binding-win32-arm64-msvc": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.4.1.tgz", - "integrity": "sha512-KyJiIne/AqV4IW0wyQO34wSMuJwy3VxVQOfIXIPyQ/Up6y/zi2P/WwXb78gHsLiGRUqCA9LOoCX+6dQZde0g1g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@unrs/resolver-binding-win32-ia32-msvc": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.4.1.tgz", - "integrity": "sha512-y2NUD7pygrBolN2NoXUrwVqBpKPhF8DiSNE5oB5/iFO49r2DpoYqdj5HPb3F42fPBH5qNqj6Zg63+xCEzAD2hw==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, "node_modules/@unrs/resolver-binding-win32-x64-msvc": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.4.1.tgz", @@ -3325,6 +2907,17 @@ "node": ">=4" } }, + "node_modules/axios": { + "version": "1.8.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.8.4.tgz", + "integrity": "sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, "node_modules/axobject-query": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", @@ -5571,6 +5164,26 @@ "node": ">=12" } }, + "node_modules/follow-redirects": { + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, "node_modules/for-each": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", @@ -5677,18 +5290,34 @@ "url": "https://github.com/sponsors/rawify" } }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "hasInstallScript": true, + "node_modules/framer-motion": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-6.5.1.tgz", + "integrity": "sha512-o1BGqqposwi7cgDrtg0dNONhkmPsUFDaLcKXigzuTFC5x58mE8iyTazxSudFzmT6MEyJKfjjU8ItoMe3W+3fiw==", "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + "dependencies": { + "@motionone/dom": "10.12.0", + "framesync": "6.0.1", + "hey-listen": "^1.0.8", + "popmotion": "11.0.3", + "style-value-types": "5.0.0", + "tslib": "^2.1.0" + }, + "optionalDependencies": { + "@emotion/is-prop-valid": "^0.8.2" + }, + "peerDependencies": { + "react": ">=16.8 || ^17.0.0 || ^18.0.0", + "react-dom": ">=16.8 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/framesync": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/framesync/-/framesync-6.0.1.tgz", + "integrity": "sha512-fUY88kXvGiIItgNC7wcTOl0SNRCVXMKSWW2Yzfmn7EKNc+MpCzcz9DhdHcdjbrtN3c6R4H5dTY2jiCpPdysEjA==", + "license": "MIT", + "dependencies": { + "tslib": "^2.1.0" } }, "node_modules/function-bind": { @@ -6130,6 +5759,12 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/hey-listen": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/hey-listen/-/hey-listen-1.0.8.tgz", + "integrity": "sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q==", + "license": "MIT" + }, "node_modules/hls.js": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/hls.js/-/hls.js-1.6.1.tgz", @@ -7309,6 +6944,12 @@ "three": ">=0.134.0" } }, + "node_modules/material-ripple-effects": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/material-ripple-effects/-/material-ripple-effects-2.0.1.tgz", + "integrity": "sha512-hHlUkZAuXbP94lu02VgrPidbZ3hBtgXBtjlwR8APNqOIgDZMV8MCIcsclL8FmGJQHvnORyvoQgC965vPsiyXLQ==", + "license": "MIT" + }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -8706,6 +8347,18 @@ "node": ">=10" } }, + "node_modules/popmotion": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/popmotion/-/popmotion-11.0.3.tgz", + "integrity": "sha512-Y55FLdj3UxkR7Vl3s7Qr4e9m0onSnP8W7d/xQLsoJM40vs6UKHFdygs6SWryasTZYqugMjm3BepCF4CWXDiHgA==", + "license": "MIT", + "dependencies": { + "framesync": "6.0.1", + "hey-listen": "^1.0.8", + "style-value-types": "5.0.0", + "tslib": "^2.1.0" + } + }, "node_modules/possible-typed-array-names": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", @@ -8931,6 +8584,12 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -10273,6 +9932,16 @@ "inline-style-parser": "0.2.4" } }, + "node_modules/style-value-types": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/style-value-types/-/style-value-types-5.0.0.tgz", + "integrity": "sha512-08yq36Ikn4kx4YU6RD7jWEv27v4V+PUsOGa4n/as8Et3CuODMJQ00ENeAVXAeydX4Z2j1XHZF1K2sX4mGl18fA==", + "license": "MIT", + "dependencies": { + "hey-listen": "^1.0.8", + "tslib": "^2.1.0" + } + }, "node_modules/styled-jsx": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz", @@ -10377,33 +10046,33 @@ } }, "node_modules/tailwindcss": { - "version": "3.4.17", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.17.tgz", - "integrity": "sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.1.tgz", + "integrity": "sha512-qAYmXRfk3ENzuPBakNK0SRrUDipP8NQnEY6772uDhflcQz5EhRdD7JNZxyrFHVQNCwULPBn6FNPp9brpO7ctcA==", "license": "MIT", "dependencies": { "@alloc/quick-lru": "^5.2.0", "arg": "^5.0.2", - "chokidar": "^3.6.0", + "chokidar": "^3.5.3", "didyoumean": "^1.2.2", "dlv": "^1.1.3", - "fast-glob": "^3.3.2", + "fast-glob": "^3.3.0", "glob-parent": "^6.0.2", "is-glob": "^4.0.3", - "jiti": "^1.21.6", - "lilconfig": "^3.1.3", - "micromatch": "^4.0.8", + "jiti": "^1.19.1", + "lilconfig": "^2.1.0", + "micromatch": "^4.0.5", "normalize-path": "^3.0.0", "object-hash": "^3.0.0", - "picocolors": "^1.1.1", - "postcss": "^8.4.47", + "picocolors": "^1.0.0", + "postcss": "^8.4.23", "postcss-import": "^15.1.0", "postcss-js": "^4.0.1", - "postcss-load-config": "^4.0.2", - "postcss-nested": "^6.2.0", - "postcss-selector-parser": "^6.1.2", - "resolve": "^1.22.8", - "sucrase": "^3.35.0" + "postcss-load-config": "^4.0.1", + "postcss-nested": "^6.0.1", + "postcss-selector-parser": "^6.0.11", + "resolve": "^1.22.2", + "sucrase": "^3.32.0" }, "bin": { "tailwind": "lib/cli.js", @@ -10459,6 +10128,15 @@ "jiti": "bin/jiti.js" } }, + "node_modules/tailwindcss/node_modules/lilconfig": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", + "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, "node_modules/thenify": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", diff --git a/package.json b/package.json index 05e92e3..2d2a57c 100644 --- a/package.json +++ b/package.json @@ -13,8 +13,10 @@ "@fontsource/poppins": "^5.2.5", "@fontsource/public-sans": "^5.2.5", "@headlessui/react": "^2.2.1", + "@heroicons/react": "^2.2.0", "@langchain/core": "^0.3.44", "@langchain/openai": "^0.5.5", + "@material-tailwind/react": "^2.1.10", "@radix-ui/react-dialog": "^1.1.6", "@radix-ui/react-icons": "^1.3.2", "@radix-ui/react-slot": "^1.1.2", @@ -22,6 +24,7 @@ "@react-three/fiber": "^8.16.0", "@types/d3-force": "^3.0.10", "@vercel/analytics": "^1.5.0", + "axios": "^1.8.4", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "d3": "^7.9.0", @@ -62,7 +65,7 @@ "@types/d3-selection": "^3.0.11", "@types/d3-zoom": "^3.0.8", "@types/node": "^20", - "@types/react": "^18.3.5", + "@types/react": "^18.2.42", "@types/react-dom": "^18.3.0", "@types/react-slick": "^0.23.13", "@types/react-virtualized-auto-sizer": "^1.0.4", diff --git a/public/images/auth-bg.jpg b/public/images/auth-bg.jpg new file mode 100644 index 0000000..2e66a49 --- /dev/null +++ b/public/images/auth-bg.jpg @@ -0,0 +1,2 @@ + +AccessDeniedAccess DeniedT3WYDG1N0KPH1NG7ANeE+zNazkkkcCjfZ9thSuYkPo2MVag3remsvenWY8hsVfnba+cojTQu0X/pG2DkxCaUOB/R2Pg= \ No newline at end of file diff --git a/src/app/(Dashboard)/dashboard/analytics/page.tsx b/src/app/(Dashboard)/dashboard/analytics/page.tsx new file mode 100644 index 0000000..9441197 --- /dev/null +++ b/src/app/(Dashboard)/dashboard/analytics/page.tsx @@ -0,0 +1,538 @@ +'use client' + +import React, { useState } from 'react'; +import { + UsersIcon, + CreditCardIcon, + ChartBarIcon, + CheckCircleIcon, + ClipboardDocumentCheckIcon, + ArrowRightIcon, + DocumentTextIcon, + DocumentDuplicateIcon, +} from '@heroicons/react/24/outline'; +import { + Card, + Typography, + Dialog, + DialogHeader, + DialogBody, + DialogFooter, + Tabs, + TabsHeader, + TabsBody, + Tab, + TabPanel, + Button, + Alert, +} from "@material-tailwind/react"; + +// Analytics Dashboard component for data visualization +const Analytics: React.FC = () => { + const [activeTab, setActiveTab] = useState("daily"); + const [showModal, setShowModal] = useState(false); + const [modalType, setModalType] = useState(''); + const [showAlert, setShowAlert] = useState(false); + + // Sample data for analytics + const dailyData = [ + { date: 'Mon', users: 120, revenue: 1250, tasks: 45 }, + { date: 'Tue', users: 132, revenue: 1480, tasks: 52 }, + { date: 'Wed', users: 101, revenue: 1120, tasks: 38 }, + { date: 'Thu', users: 134, revenue: 1460, tasks: 57 }, + { date: 'Fri', users: 150, revenue: 1700, tasks: 62 }, + { date: 'Sat', users: 120, revenue: 1380, tasks: 48 }, + { date: 'Sun', users: 95, revenue: 990, tasks: 36 } + ]; + + const weeklyData = [ + { date: 'Week 1', users: 820, revenue: 8450, tasks: 312 }, + { date: 'Week 2', users: 932, revenue: 9280, tasks: 352 }, + { date: 'Week 3', users: 901, revenue: 9020, tasks: 338 }, + { date: 'Week 4', users: 934, revenue: 9660, tasks: 357 } + ]; + + const monthlyData = [ + { date: 'Jan', users: 3220, revenue: 34250, tasks: 1245 }, + { date: 'Feb', users: 3932, revenue: 42280, tasks: 1352 }, + { date: 'Mar', users: 3901, revenue: 41020, tasks: 1338 }, + { date: 'Apr', users: 4134, revenue: 43660, tasks: 1457 }, + { date: 'May', users: 4432, revenue: 46280, tasks: 1542 }, + { date: 'Jun', users: 4401, revenue: 45020, tasks: 1498 } + ]; + + const showSuccessAlert = () => { + setShowAlert(true); + setTimeout(() => setShowAlert(false), 3000); + }; + + const openModal = (type: string) => { + setModalType(type); + setShowModal(true); + }; + + return ( +
+ {showAlert && ( + } + onClose={() => setShowAlert(false)} + > + Report generated successfully! Check your email inbox. + + )} + + {/* Header Card */} + +
+
+
+
+ + Analytics Dashboard +
+ + Performance Metrics + + + Track your business performance with real-time analytics + +
+
+ + +
+
+
+ {/* Decorative elements */} +
+
+
+ + {/* Analytics Time Period Tabs */} + + + + setActiveTab("daily")}> + Daily + + setActiveTab("weekly")}> + Weekly + + setActiveTab("monthly")}> + Monthly + + + + +
+ +
+
+ +
+
+ Daily Users + {dailyData.reduce((sum, item) => sum + item.users, 0) / dailyData.length} + +5.2% vs last week +
+
+
+ +
+
+ +
+
+ Daily Revenue + ${dailyData.reduce((sum, item) => sum + item.revenue, 0) / dailyData.length} + +8.4% vs last week +
+
+
+ +
+
+ +
+
+ Tasks Completed + {dailyData.reduce((sum, item) => sum + item.tasks, 0) / dailyData.length} + +3.8% vs last week +
+
+
+
+ + {/* Chart Placeholder */} + +
+ + Daily Performance Chart + + Shows user activity, revenue, and task completion for the past 7 days + + +
+
+
+ + +
+ +
+
+ +
+
+ Weekly Users + {weeklyData.reduce((sum, item) => sum + item.users, 0) / weeklyData.length} + +12.1% vs last month +
+
+
+ +
+
+ +
+
+ Weekly Revenue + ${weeklyData.reduce((sum, item) => sum + item.revenue, 0) / weeklyData.length} + +15.4% vs last month +
+
+
+ +
+
+ +
+
+ Tasks Completed + {weeklyData.reduce((sum, item) => sum + item.tasks, 0) / weeklyData.length} + +9.7% vs last month +
+
+
+
+ + {/* Chart Placeholder */} + +
+ + Weekly Performance Chart + + Shows user activity, revenue, and task completion for the past 4 weeks + + +
+
+
+ +
+ +
+
+ +
+
+ Monthly Users + {monthlyData.reduce((sum, item) => sum + item.users, 0) / monthlyData.length} + +18.3% vs last quarter +
+
+
+ +
+
+ +
+
+ Monthly Revenue + ${monthlyData.reduce((sum, item) => sum + item.revenue, 0) / monthlyData.length} + +21.7% vs last quarter +
+
+
+ +
+
+ +
+
+ Tasks Completed + {monthlyData.reduce((sum, item) => sum + item.tasks, 0) / monthlyData.length} + +14.2% vs last quarter +
+
+
+
+{/* Chart Placeholder */} + +
+ + Monthly Performance Chart + + Shows user activity, revenue, and task completion for the past 6 months + + +
+
+
+
+
+
+ + {/* Recent Activity */} + + + Recent Activity + +
+
+
+ +
+
+ New user registration + User "john.smith@example.com" has registered + 2 hours ago +
+
+ +
+
+ +
+
+ New subscription + User "acme-corp" purchased Enterprise plan + 4 hours ago +
+
+ +
+
+ +
+
+ Analytics report generated + Monthly report for February 2025 is ready + 8 hours ago +
+
+
+ + +
+ + {/* Modals */} + setShowModal(false)} + size="md" + > + + {modalType === 'export' && 'Export Data'} + {modalType === 'chart' && 'Detailed Analytics Chart'} + {modalType === 'activity' && 'All Activity Log'} + + + {modalType === 'export' && ( +
+
+ + Select Data Range + + +
+ +
+ + Data Format + +
+ + + +
+
+ +
+ + Include Metrics + +
+ + + + +
+
+
+ )} + + {modalType === 'chart' && ( +
+
+
+ + Interactive Chart Visualization + + In a production environment, this would display an interactive chart showing detailed analytics data based on the selected time period + +
+
+ +
+
+ Total Users + 24,892 + +12.3% +
+ +
+ Revenue + $198,453 + +15.7% +
+ +
+ Avg. Conversion + 3.8% + +0.5% +
+
+
+ )} + + {modalType === 'activity' && ( +
+ {Array.from({ length: 10 }).map((_, index) => ( +
+
+ {index % 3 === 0 && } + {index % 3 === 1 && } + {index % 3 === 2 && } +
+
+ + {index % 3 === 0 && 'User Activity'} + {index % 3 === 1 && 'Billing Event'} + {index % 3 === 2 && 'System Event'} + + + {index % 3 === 0 && `User "${['john', 'mary', 'alex', 'sarah', 'mike'][index % 5]}@example.com" performed an action`} + {index % 3 === 1 && 'Subscription plan change or payment processed'} + {index % 3 === 2 && 'System maintenance or report generation'} + + {index + 1} hour{index !== 0 ? 's' : ''} ago +
+
+ ))} +
+ )} +
+ + + + +
+
+ ); +}; + +export default Analytics; \ No newline at end of file diff --git a/src/app/(Dashboard)/dashboard/dashboard.css b/src/app/(Dashboard)/dashboard/dashboard.css new file mode 100644 index 0000000..5beafc7 --- /dev/null +++ b/src/app/(Dashboard)/dashboard/dashboard.css @@ -0,0 +1,17 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +@layer base { + :root { + font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; + line-height: 1.5; + font-weight: 400; + } + + body { + margin: 0; + min-width: 320px; + min-height: 100vh; + } +} \ No newline at end of file diff --git a/src/app/(Dashboard)/dashboard/guests/page.tsx b/src/app/(Dashboard)/dashboard/guests/page.tsx new file mode 100644 index 0000000..988b981 --- /dev/null +++ b/src/app/(Dashboard)/dashboard/guests/page.tsx @@ -0,0 +1,860 @@ +'use client' + +import React, { useState, useEffect } from 'react'; +import { ArrowPathIcon, EyeIcon, HomeIcon, MagnifyingGlassIcon, MinusIcon, PencilIcon, PlusIcon, TrashIcon } from '@heroicons/react/24/outline'; +import axios from 'axios'; +import { + Card, + CardHeader, + CardBody, + Typography, + Input, + Chip, + IconButton, + Button, + Dialog, + DialogHeader, + DialogBody, + DialogFooter, + Alert, +} from "@material-tailwind/react"; +import { API_URL } from '@/utils/axiosConfig' +import { v4 as uuidv4 } from 'uuid'; + +interface Interaction { + event: string, + timestamp: string, +} + +interface Guest { + additional_notes?: string; + budget?: string; + company?: string; + contact_info?: string; + created_at?: string; + current_tech?: string[]; + first_visit_timestamp?: string; + id?: string; + industry?: string; + interaction_events?: string[]; + interaction_history?: Interaction[]; + name?: string; + page_views?: string[]; + pain_points?: string[]; + project_type?: string[]; + session_id?: string; + status?: 'NEW' | 'CONTACTED' | 'CONVERTED'; + timeline?: string; + updated_at?: string; +} + +const GuestsTable: React.FC = () => { + const [guests, setGuests] = useState([]); + const [loading, setLoading] = useState(true); + const [searchTerm, setSearchTerm] = useState(''); + const [currentPage, setCurrentPage] = useState(1); + const [selectedGuest, setSelectedGuest] = useState(null); + const [isCreateModalOpen, setIsCreateModalOpen] = useState(false); + const [isViewModalOpen, setIsViewModalOpen] = useState(false); + const [isEditModalOpen, setIsEditModalOpen] = useState(false); + const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false); + const [createFormData, setCreateFormData] = useState({}); + const [numProjectTypeFields, setNumProjectTypeFields] = useState(1); + const [numPainPointFields, setNumPainPointFields] = useState(1); + const [numCurrentTechFields, setNumCurrentTechFields] = useState(1); + const [editFormData, setEditFormData] = useState({}); + const [showError, setShowError] = useState(false); + const itemsPerPage = 10; + + useEffect(() => { + fetchGuests(); + }, []); + + const fetchGuests = async () => { + setLoading(true); + try { + const res = await axios.get(`${API_URL}/guests/`); + if(!(Array.isArray(res.data) && res.data.every(guest => typeof guest === 'object'))) { + setShowError(true); + throw Error //Ensure an array of guests is returned + } else setShowError(false); + setGuests(res.data); + } catch { + setShowError(true); + } + setLoading(false); + }; + + const handleView = (guest: Guest) => { + setSelectedGuest(guest); + setIsViewModalOpen(true); + } + + const handleCreate = () => { + setNumProjectTypeFields(1); + setNumPainPointFields(1); + setNumCurrentTechFields(1); + setIsCreateModalOpen(true); + }; + + const handleEdit = (guest: Guest) => { + setSelectedGuest(guest); + setNumProjectTypeFields(guest.project_type ? guest.project_type.length : 0); + setNumPainPointFields(guest.pain_points ? guest.pain_points.length : 0); + setNumCurrentTechFields(guest.current_tech ? guest.current_tech.length: 0); + setEditFormData(guest); + setIsEditModalOpen(true); + }; + + const handleDelete = (guest: Guest) => { + setSelectedGuest(guest); + setIsDeleteModalOpen(true); + }; + + const handleCreateSubmit = async () => { + if (!createFormData) return; + + try { + createFormData.session_id = uuidv4(); + await axios.post(`${API_URL}/guests/`, createFormData); + + // Update guests + fetchGuests(); + + setIsCreateModalOpen(false); + setCreateFormData({}); + } catch (error) { + console.error('Error creating guest:', error); + // Handle error (show error message to user) + } + }; + + const handleEditSubmit = async () => { + if (!editFormData) return; + + try { + await axios.put(`${API_URL}/guests/${editFormData.id}`, editFormData); + + // Update guests + fetchGuests(); + + setIsEditModalOpen(false); + setEditFormData({}); + } catch (error) { + console.error('Error updating guest:', error); + // Handle error (show error message to user) + } + }; + + const handleDeleteConfirm = async () => { + if (!selectedGuest) return; + + try { + await axios.delete(`${API_URL}/guests/${selectedGuest.id}`); + + // Update guests + fetchGuests(); + + setIsDeleteModalOpen(false); + setSelectedGuest(null); + } catch (error) { + console.error('Error deleting guest:', error); + // Handle error (show error message to user) + } + }; + + const getStatusColor = (status: Guest['status']) => { + switch (status) { + case 'NEW': + return 'blue'; + case 'CONTACTED': + return 'amber'; + case 'CONVERTED': + return 'green'; + default: + return 'gray'; + } + }; + + const filteredGuests = guests.filter(guest => + searchTerm.toLowerCase() === '' ? true : + (guest.name ? guest.name.toLowerCase().includes(searchTerm.toLowerCase()) : false) || + (guest.company ? guest.company.toLowerCase().includes(searchTerm.toLowerCase()) : false) || + (guest.industry ? guest.industry.toLowerCase().includes(searchTerm.toLowerCase()) : false) || + (guest.budget ? guest.budget.toLowerCase().includes(searchTerm.toLowerCase()) : false) || + (guest.contact_info ? guest.contact_info.toLowerCase().includes(searchTerm.toLowerCase()) : false) || + (guest.status ? guest.status.toLowerCase().includes(searchTerm.toLowerCase()) : false) + ); + + const paginatedGuests = filteredGuests.slice( + (currentPage - 1) * itemsPerPage, + currentPage * itemsPerPage + ); + + const totalPages = Math.ceil(filteredGuests.length / itemsPerPage); + + const TABLE_HEAD = ["Name", "Company", "Industry", "Budget", "Contact", "Status", "Last Interaction", "Actions"]; + + const viewField = (field: string, value: string | undefined) => { + return ( +
+ + {field} + + 0 ? "overscroll-x-contain overflow-auto border-black border-2 h-min w-full" : + "overscroll-x-contain overflow-auto border-black border-2 w-full" : + "overscroll-x-contain overflow-auto w-full"}> + + {value ? value : ''} + + +
+ ) + } + if(showError) return ( + + + + } + > + Failed to retrieve guests + + ) + return ( + +
+
+ + Guest Management + + + View and manage guest accounts in your system + +
+ +
+ + +
+
+ + Guests list + + + See information about all guests + +
+
+
+ + + +
+
+ } + value={searchTerm} + onChange={(e) => setSearchTerm(e.target.value)} + crossOrigin={undefined} + /> +
+
+
+
+ + + + + {TABLE_HEAD.map((head) => ( + + ))} + + + + {loading ? ( + + + + ) : ( + paginatedGuests.map((guest, index) => { + const isLast = index === paginatedGuests.length - 1; + const classes = isLast ? "p-4" : "p-4 border-b border-blue-gray-50"; + return ( + + + + + + + + + + + ); + }) + )} + +
+ + {head} + +
+ + Loading... + +
+ + {guest.name ? guest.name : ''} + + + + {guest.company ? guest.company : ''} + + + + {guest.industry ? guest.industry : ''} + + + + {guest.budget ? guest.budget : ''} + + + + {guest.contact_info ? guest.contact_info : ''} + + +
+ +
+
+ + {guest.interaction_history && guest.interaction_history.length > 0 ? guest.interaction_history[guest.interaction_history.length-1].timestamp : 'None'} + + +
+ handleView(guest)} + > + + + handleEdit(guest)} + > + + + handleDelete(guest)} + > + + +
+
+
+
+ + Page {currentPage} of {totalPages} + +
+ + +
+
+ + {/* Create Modal */} + setIsCreateModalOpen(false)} + > + Create Guest + +
+ setCreateFormData({ ...createFormData, name: e.target.value })} + crossOrigin={undefined} + /> + setCreateFormData({ ...createFormData, company: e.target.value })} + crossOrigin={undefined} + /> + setCreateFormData({ ...createFormData, industry: e.target.value })} + crossOrigin={undefined} + /> + setCreateFormData({ ...createFormData, budget: e.target.value })} + crossOrigin={undefined} + /> + setCreateFormData({ ...createFormData, timeline: e.target.value })} + crossOrigin={undefined} + /> + setCreateFormData({ ...createFormData, contact_info: e.target.value })} + crossOrigin={undefined} + /> + setCreateFormData({ ...createFormData, additional_notes: e.target.value })} + crossOrigin={undefined} + /> + { + // Create project type fields based on numProjectTypeFields + Array.from({length: numProjectTypeFields}, (_, num) => num+1 && + setCreateFormData({ ...createFormData, project_type: createFormData.project_type ? createFormData.project_type.map((value, i) => (i === num ? e.target.value : value)) : [e.target.value] })} + crossOrigin={undefined} + />) + } +
+ + +
+ { + // Create pain point fields based on numPainPointFields + Array.from({length: numPainPointFields}, (_, num) => num+1 && + setCreateFormData({ ...createFormData, pain_points: createFormData.pain_points ? createFormData.pain_points.map((value, i) => (i === num ? e.target.value : value)) : [e.target.value] })} + crossOrigin={undefined} + />) + } +
+ + +
+ { + // Create current tech fields based on numCurrentTechFields + Array.from({length: numCurrentTechFields}, (_, num) => num+1 && + setCreateFormData({ ...createFormData, current_tech: createFormData.current_tech ? createFormData.current_tech.map((value, i) => (i === num ? e.target.value : value)) : [e.target.value] })} + crossOrigin={undefined} + />) + } +
+ + +
+
+ + Status + + +
+
+
+ + + + +
+ + {/* View Modal */} + setIsViewModalOpen(false)} + > + View Guest + +
{/*Fix jest detecting no children in DialogBody error*/}
+ {selectedGuest && ( +
+ {viewField('Name:', selectedGuest.name)} + {viewField('Id:', String(selectedGuest.id))} + {viewField('Session Id:', selectedGuest.session_id)} + {viewField('Company:', selectedGuest.company)} + {viewField('Industry:', selectedGuest.industry)} + {viewField('Budget:', selectedGuest.budget)} + {viewField('Contact:', selectedGuest.contact_info)} + {viewField('Timeline:', selectedGuest.timeline)} + {viewField('Additional Notes:', selectedGuest.additional_notes)} + {viewField('Status:', selectedGuest.status)} + {viewField('Created At:', selectedGuest.created_at)} + {viewField('Updated At:', selectedGuest.updated_at)} + {viewField('First Visit Time:', selectedGuest.first_visit_timestamp)} + {viewField('Interaction History:', selectedGuest.interaction_history ? selectedGuest.interaction_history.map(obj => `${obj.event} at ${obj.timestamp}`).join(', ') : undefined)} + {viewField('Interaction Events:', selectedGuest.interaction_events ? selectedGuest.interaction_events.join(', ') : undefined)} + {viewField('Project Types:', selectedGuest.project_type ? selectedGuest.project_type.join(', ') : undefined)} + {viewField('Pain Points:', selectedGuest.pain_points? selectedGuest.pain_points.join(', ') : undefined)} + {viewField('Current Tech:', selectedGuest.current_tech ? selectedGuest.current_tech.join(', ') : undefined)} + {viewField('Page Views:', selectedGuest.page_views ? selectedGuest.page_views.join(', ') : undefined)} +
+ )} +
+ + + +
+ + {/* Edit Modal */} + setIsEditModalOpen(false)} + > + Edit Guest + +
+ setEditFormData({ ...editFormData, name: e.target.value })} + crossOrigin={undefined} + /> + setEditFormData({ ...editFormData, company: e.target.value })} + crossOrigin={undefined} + /> + setEditFormData({ ...editFormData, industry: e.target.value })} + crossOrigin={undefined} + /> + setEditFormData({ ...editFormData, budget: e.target.value })} + crossOrigin={undefined} + /> + setEditFormData({ ...editFormData, timeline: e.target.value })} + crossOrigin={undefined} + /> + setEditFormData({ ...editFormData, contact_info: e.target.value })} + crossOrigin={undefined} + /> + setEditFormData({ ...editFormData, additional_notes: e.target.value })} + crossOrigin={undefined} + /> + { + // Create project type fields based on numProjectTypeFields + Array.from({length: numProjectTypeFields}, (_, num) => num+1 && + setEditFormData({ ...editFormData, project_type: editFormData.project_type ? editFormData.project_type.map((value, i) => (i === num ? e.target.value : value)) : [e.target.value] })} + crossOrigin={undefined} + />) + } +
+ + +
+ { + // Create pain point fields based on numPainPointFields + Array.from({length: numPainPointFields}, (_, num) => num+1 && + setEditFormData({ ...editFormData, pain_points: editFormData.pain_points ? editFormData.pain_points.map((value, i) => (i === num ? e.target.value : value)) : [e.target.value] })} + crossOrigin={undefined} + />) + } +
+ + +
+ { + // Create current tech fields based on numCurrentTechFields + Array.from({length: numCurrentTechFields}, (_, num) => num+1 && + setEditFormData({ ...editFormData, current_tech: editFormData.current_tech ? editFormData.current_tech.map((value, i) => (i === num ? e.target.value : value)) : [e.target.value] })} + crossOrigin={undefined} + />) + } +
+ + +
+
+ + Status + + +
+
+
+ + + + +
+ + {/* DeleteConfirmation Modal */} + setIsDeleteModalOpen(false)} + > + Confirm Deletion + + Are you sure you want to delete {selectedGuest?.name}? This action cannot be undone. + + + + + + +
+
+ ); +} + +export default GuestsTable; \ No newline at end of file diff --git a/src/app/(Dashboard)/dashboard/knowledge/page.tsx b/src/app/(Dashboard)/dashboard/knowledge/page.tsx new file mode 100644 index 0000000..2e357fc --- /dev/null +++ b/src/app/(Dashboard)/dashboard/knowledge/page.tsx @@ -0,0 +1,285 @@ +'use client' + +import React, { useState } from 'react'; +import { + PlusIcon, + MagnifyingGlassIcon, + ArrowDownOnSquareIcon, + ChevronDownIcon +} from '@heroicons/react/24/outline'; +import { + Typography, + Card, + CardBody, + Button, + Menu, + MenuHandler, + MenuList, + MenuItem, + Input, + Dialog, + DialogHeader, + DialogBody, + DialogFooter, + Tabs, + TabsHeader, + Tab, + Select, + Option, + Textarea +} from "@material-tailwind/react"; +import KnowledgeGraph from '@/components/Dashboard/KnowledgeGraph'; + +export function KnowledgeGraphPage() { + const [isAddNodeModalOpen, setIsAddNodeModalOpen] = useState(false); + const [isAddRelationModalOpen, setIsAddRelationModalOpen] = useState(false); + const [activeTab, setActiveTab] = useState("visualization"); + + const handleExport = (format: string) => { + console.log(`Exporting in ${format} format`); + // Implementationwould go here + }; + + return ( +
+ {/* Header Section */} + +
+
+
+ + Knowledge Graph + + + Visual representation of concepts, entities, and their relationships + +
+
+ + + + + + + + + + handleExport('json')}>JSON + handleExport('csv')}>CSV + handleExport('pdf')}>PDF + handleExport('png')}>PNG Image + + +
+
+
+ {/* Decorative elements */} +
+
+
+ + {/* Tabs */} + + + setActiveTab("visualization")}> + Visualization + + setActiveTab("list")}> + List View + + setActiveTab("analytics")}> + Analytics + + + + + {/* Main Content */} +
+ {activeTab === "visualization" && ( + + )} + + {activeTab === "list" && ( + + +
+
+ } + label="Search nodes and relationships" + crossOrigin={undefined} + /> +
+
+ +
+ + List View Coming Soon + + + This feature is currently under development + +
+
+
+ )} + + {activeTab === "analytics" && ( + + +
+ + Analytics View Coming Soon + + + This feature is currently under development + +
+
+
+ )} +
+ + {/* Add Node Modal */} + setIsAddNodeModalOpen(false)} + size="md" + > + Add New Node + +
+
+ + Node Label + + +
+
+ + Node Type + + +
+
+ + Description + +