Full Chat Interface and added the other sections below

This commit is contained in:
codebox283 2025-06-24 18:28:47 +05:30
parent c9e0114586
commit 85ef56f301
19 changed files with 1012 additions and 239 deletions

2
.env.example Normal file
View File

@ -0,0 +1,2 @@
# Google Gemini API Key
NEXT_PUBLIC_GEMINI_API_KEY=AIzaSyAK8AyA8JYTprpqIif4qBiPql84Uh0VFh4

View File

@ -21,6 +21,8 @@
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Fredoka:wght@300..700&family=Nunito:ital,wght@0,200..1000;1,200..1000&family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&family=Quicksand:wght@300..700&display=swap" rel="stylesheet">
</head>
<body style="font-family: 'Inter', sans-serif;">

138
package-lock.json generated
View File

@ -8,6 +8,7 @@
"name": "vite_react_shadcn_ts",
"version": "0.0.0",
"dependencies": {
"@google/generative-ai": "^0.24.1",
"@hookform/resolvers": "^3.9.0",
"@radix-ui/react-accordion": "^1.2.0",
"@radix-ui/react-alert-dialog": "^1.1.1",
@ -55,6 +56,7 @@
"recharts": "^2.12.7",
"sonner": "^1.5.0",
"tailwind-merge": "^2.5.2",
"tailwind-scrollbar-hide": "^4.0.0",
"tailwindcss-animate": "^1.0.7",
"vaul": "^0.9.3",
"zod": "^3.23.8"
@ -83,7 +85,6 @@
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz",
"integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=10"
@ -750,6 +751,15 @@
"integrity": "sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig==",
"license": "MIT"
},
"node_modules/@google/generative-ai": {
"version": "0.24.1",
"resolved": "https://registry.npmjs.org/@google/generative-ai/-/generative-ai-0.24.1.tgz",
"integrity": "sha512-MqO+MLfM6kjxcKoy0p1wRzG3b4ZZXtPI+z2IE26UogS2Cm/XHO+7gGRBh6gcJsOiIVoH93UwKvW4HdgiOZCy9Q==",
"license": "Apache-2.0",
"engines": {
"node": ">=18.0.0"
}
},
"node_modules/@hookform/resolvers": {
"version": "3.9.0",
"resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-3.9.0.tgz",
@ -815,7 +825,6 @@
"version": "8.0.2",
"resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
"integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
"dev": true,
"license": "ISC",
"dependencies": {
"string-width": "^5.1.2",
@ -833,7 +842,6 @@
"version": "0.3.5",
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz",
"integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@jridgewell/set-array": "^1.2.1",
@ -848,7 +856,6 @@
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
"integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6.0.0"
@ -858,7 +865,6 @@
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
"integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6.0.0"
@ -868,14 +874,12 @@
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
"integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
"dev": true,
"license": "MIT"
},
"node_modules/@jridgewell/trace-mapping": {
"version": "0.3.25",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
"integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@jridgewell/resolve-uri": "^3.1.0",
@ -886,7 +890,6 @@
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
"integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
"dev": true,
"license": "MIT",
"dependencies": {
"@nodelib/fs.stat": "2.0.5",
@ -900,7 +903,6 @@
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
"integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 8"
@ -910,7 +912,6 @@
"version": "1.2.8",
"resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
"integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@nodelib/fs.scandir": "2.1.5",
@ -924,7 +925,6 @@
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
"integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
"dev": true,
"license": "MIT",
"optional": true,
"engines": {
@ -2925,14 +2925,14 @@
"version": "15.7.13",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.13.tgz",
"integrity": "sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==",
"dev": true,
"devOptional": true,
"license": "MIT"
},
"node_modules/@types/react": {
"version": "18.3.12",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.12.tgz",
"integrity": "sha512-D2wOSq/d6Agt28q7rSI3jhU7G6aiuzljDGZ2hTZHIkrTLUI+AF3WMeKkEZ9nN2fkBAlcktT6vcZjDFiIhMYEQw==",
"dev": true,
"devOptional": true,
"license": "MIT",
"dependencies": {
"@types/prop-types": "*",
@ -2943,7 +2943,7 @@
"version": "18.3.1",
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.1.tgz",
"integrity": "sha512-qW1Mfv8taImTthu4KoXgDfLuk4bydU6Q/TkADnDWWHwi4NX4BR+LWfTp2sVmTqRrsHvyDDTelgelxJ+SsejKKQ==",
"dev": true,
"devOptional": true,
"license": "MIT",
"dependencies": {
"@types/react": "*"
@ -3235,7 +3235,6 @@
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz",
"integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=12"
@ -3248,7 +3247,6 @@
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"license": "MIT",
"dependencies": {
"color-convert": "^2.0.1"
@ -3264,14 +3262,12 @@
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
"integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==",
"dev": true,
"license": "MIT"
},
"node_modules/anymatch": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
"integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
"dev": true,
"license": "ISC",
"dependencies": {
"normalize-path": "^3.0.0",
@ -3285,7 +3281,6 @@
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
"integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==",
"dev": true,
"license": "MIT"
},
"node_modules/argparse": {
@ -3349,14 +3344,12 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"dev": true,
"license": "MIT"
},
"node_modules/binary-extensions": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
"integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
@ -3380,7 +3373,6 @@
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
"dev": true,
"license": "MIT",
"dependencies": {
"fill-range": "^7.1.1"
@ -3436,7 +3428,6 @@
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz",
"integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 6"
@ -3484,7 +3475,6 @@
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
"integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
"dev": true,
"license": "MIT",
"dependencies": {
"anymatch": "~3.1.2",
@ -3509,7 +3499,6 @@
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
"dev": true,
"license": "ISC",
"dependencies": {
"is-glob": "^4.0.1"
@ -3920,7 +3909,6 @@
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"color-name": "~1.1.4"
@ -3933,14 +3921,12 @@
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true,
"license": "MIT"
},
"node_modules/commander": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
"integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 6"
@ -3957,7 +3943,6 @@
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
"dev": true,
"dependencies": {
"path-key": "^3.1.0",
"shebang-command": "^2.0.0",
@ -3971,7 +3956,6 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
"integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
"dev": true,
"license": "MIT",
"bin": {
"cssesc": "bin/cssesc"
@ -4158,14 +4142,12 @@
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz",
"integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==",
"dev": true,
"license": "Apache-2.0"
},
"node_modules/dlv": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz",
"integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==",
"dev": true,
"license": "MIT"
},
"node_modules/dom-helpers": {
@ -4182,7 +4164,6 @@
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
"integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
"dev": true,
"license": "MIT"
},
"node_modules/electron-to-chromium": {
@ -4224,7 +4205,6 @@
"version": "9.2.2",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
"integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
"dev": true,
"license": "MIT"
},
"node_modules/esbuild": {
@ -4503,7 +4483,6 @@
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
"integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==",
"dev": true,
"license": "MIT",
"dependencies": {
"@nodelib/fs.stat": "^2.0.2",
@ -4520,7 +4499,6 @@
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
"dev": true,
"license": "ISC",
"dependencies": {
"is-glob": "^4.0.1"
@ -4547,7 +4525,6 @@
"version": "1.17.1",
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz",
"integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==",
"dev": true,
"license": "ISC",
"dependencies": {
"reusify": "^1.0.4"
@ -4570,7 +4547,6 @@
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
"dev": true,
"license": "MIT",
"dependencies": {
"to-regex-range": "^5.0.1"
@ -4621,7 +4597,6 @@
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz",
"integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==",
"dev": true,
"license": "ISC",
"dependencies": {
"cross-spawn": "^7.0.0",
@ -4652,7 +4627,6 @@
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
"optional": true,
@ -4667,7 +4641,6 @@
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
"dev": true,
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/ljharb"
@ -4686,7 +4659,6 @@
"version": "10.4.5",
"resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
"integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
"dev": true,
"license": "ISC",
"dependencies": {
"foreground-child": "^3.1.0",
@ -4707,7 +4679,6 @@
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
"integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
"dev": true,
"license": "ISC",
"dependencies": {
"is-glob": "^4.0.3"
@ -4720,7 +4691,6 @@
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
"dev": true,
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0"
@ -4730,7 +4700,6 @@
"version": "9.0.5",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
"dev": true,
"license": "ISC",
"dependencies": {
"brace-expansion": "^2.0.1"
@ -4776,7 +4745,6 @@
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"function-bind": "^1.1.2"
@ -4854,7 +4822,6 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
"integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
"dev": true,
"license": "MIT",
"dependencies": {
"binary-extensions": "^2.0.0"
@ -4867,7 +4834,6 @@
"version": "2.15.1",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz",
"integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"hasown": "^2.0.2"
@ -4883,7 +4849,6 @@
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
@ -4893,7 +4858,6 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
@ -4903,7 +4867,6 @@
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
"dev": true,
"license": "MIT",
"dependencies": {
"is-extglob": "^2.1.1"
@ -4916,7 +4879,6 @@
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.12.0"
@ -4926,14 +4888,12 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
"dev": true,
"license": "ISC"
},
"node_modules/jackspeak": {
"version": "3.4.3",
"resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
"integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
"dev": true,
"license": "BlueOak-1.0.0",
"dependencies": {
"@isaacs/cliui": "^8.0.2"
@ -4949,7 +4909,6 @@
"version": "1.21.6",
"resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz",
"integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==",
"dev": true,
"license": "MIT",
"bin": {
"jiti": "bin/jiti.js"
@ -5023,7 +4982,6 @@
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz",
"integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=14"
@ -5036,7 +4994,6 @@
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
"integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
"dev": true,
"license": "MIT"
},
"node_modules/locate-path": {
@ -5546,7 +5503,6 @@
"version": "10.4.3",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
"integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
"dev": true,
"license": "ISC"
},
"node_modules/lucide-react": {
@ -5571,7 +5527,6 @@
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
"integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 8"
@ -5581,7 +5536,6 @@
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
"integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
"dev": true,
"license": "MIT",
"dependencies": {
"braces": "^3.0.3",
@ -5608,7 +5562,6 @@
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
"integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
"dev": true,
"license": "ISC",
"engines": {
"node": ">=16 || 14 >=14.17"
@ -5625,7 +5578,6 @@
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
"integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==",
"dev": true,
"license": "MIT",
"dependencies": {
"any-promise": "^1.0.0",
@ -5637,7 +5589,6 @@
"version": "3.3.7",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
"integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
"dev": true,
"funding": [
{
"type": "github",
@ -5680,7 +5631,6 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
@ -5709,7 +5659,6 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz",
"integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 6"
@ -5769,7 +5718,6 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
"integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
"dev": true,
"license": "BlueOak-1.0.0"
},
"node_modules/parent-module": {
@ -5799,7 +5747,6 @@
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
@ -5809,14 +5756,12 @@
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
"dev": true,
"license": "MIT"
},
"node_modules/path-scurry": {
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
"integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
"dev": true,
"license": "BlueOak-1.0.0",
"dependencies": {
"lru-cache": "^10.2.0",
@ -5833,14 +5778,12 @@
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
"dev": true,
"license": "ISC"
},
"node_modules/picomatch": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8.6"
@ -5853,7 +5796,6 @@
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
"integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
@ -5863,7 +5805,6 @@
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz",
"integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 6"
@ -5873,7 +5814,6 @@
"version": "8.4.47",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz",
"integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==",
"dev": true,
"funding": [
{
"type": "opencollective",
@ -5902,7 +5842,6 @@
"version": "15.1.0",
"resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz",
"integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==",
"dev": true,
"license": "MIT",
"dependencies": {
"postcss-value-parser": "^4.0.0",
@ -5920,7 +5859,6 @@
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz",
"integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==",
"dev": true,
"license": "MIT",
"dependencies": {
"camelcase-css": "^2.0.1"
@ -5940,7 +5878,6 @@
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz",
"integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==",
"dev": true,
"funding": [
{
"type": "opencollective",
@ -5976,7 +5913,6 @@
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz",
"integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==",
"dev": true,
"funding": [
{
"type": "opencollective",
@ -6002,7 +5938,6 @@
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz",
"integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==",
"dev": true,
"license": "MIT",
"dependencies": {
"cssesc": "^3.0.0",
@ -6016,7 +5951,6 @@
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
"integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
"dev": true,
"license": "MIT"
},
"node_modules/prelude-ls": {
@ -6060,7 +5994,6 @@
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
"integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
"dev": true,
"funding": [
{
"type": "github",
@ -6294,7 +6227,6 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
"integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==",
"dev": true,
"license": "MIT",
"dependencies": {
"pify": "^2.3.0"
@ -6304,7 +6236,6 @@
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
"integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
"dev": true,
"license": "MIT",
"dependencies": {
"picomatch": "^2.2.1"
@ -6355,7 +6286,6 @@
"version": "1.22.8",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz",
"integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==",
"dev": true,
"license": "MIT",
"dependencies": {
"is-core-module": "^2.13.0",
@ -6383,7 +6313,6 @@
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
"integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
"dev": true,
"license": "MIT",
"engines": {
"iojs": ">=1.0.0",
@ -6430,7 +6359,6 @@
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
"integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
"dev": true,
"funding": [
{
"type": "github",
@ -6476,7 +6404,6 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
"dev": true,
"license": "MIT",
"dependencies": {
"shebang-regex": "^3.0.0"
@ -6489,7 +6416,6 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
@ -6499,7 +6425,6 @@
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
"integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
"dev": true,
"license": "ISC",
"engines": {
"node": ">=14"
@ -6522,7 +6447,6 @@
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
"dev": true,
"license": "BSD-3-Clause",
"engines": {
"node": ">=0.10.0"
@ -6532,7 +6456,6 @@
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
"integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
"dev": true,
"license": "MIT",
"dependencies": {
"eastasianwidth": "^0.2.0",
@ -6551,7 +6474,6 @@
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"dev": true,
"license": "MIT",
"dependencies": {
"emoji-regex": "^8.0.0",
@ -6566,7 +6488,6 @@
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
@ -6576,14 +6497,12 @@
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
"dev": true,
"license": "MIT"
},
"node_modules/string-width-cjs/node_modules/strip-ansi": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"dev": true,
"license": "MIT",
"dependencies": {
"ansi-regex": "^5.0.1"
@ -6596,7 +6515,6 @@
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
"integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"ansi-regex": "^6.0.1"
@ -6613,7 +6531,6 @@
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"dev": true,
"license": "MIT",
"dependencies": {
"ansi-regex": "^5.0.1"
@ -6626,7 +6543,6 @@
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
@ -6649,7 +6565,6 @@
"version": "3.35.0",
"resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz",
"integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@jridgewell/gen-mapping": "^0.3.2",
@ -6685,7 +6600,6 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
"integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.4"
@ -6704,11 +6618,19 @@
"url": "https://github.com/sponsors/dcastil"
}
},
"node_modules/tailwind-scrollbar-hide": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/tailwind-scrollbar-hide/-/tailwind-scrollbar-hide-4.0.0.tgz",
"integrity": "sha512-gobtvVcThB2Dxhy0EeYSS1RKQJ5baDFkamkhwBvzvevwX6L4XQfpZ3me9s25Ss1ecFVT5jPYJ50n+7xTBJG9WQ==",
"license": "MIT",
"peerDependencies": {
"tailwindcss": ">=3.0.0 || >= 4.0.0 || >= 4.0.0-beta.8 || >= 4.0.0-alpha.20"
}
},
"node_modules/tailwindcss": {
"version": "3.4.17",
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.17.tgz",
"integrity": "sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==",
"dev": true,
"license": "MIT",
"dependencies": {
"@alloc/quick-lru": "^5.2.0",
@ -6762,7 +6684,6 @@
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz",
"integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==",
"dev": true,
"license": "MIT",
"dependencies": {
"any-promise": "^1.0.0"
@ -6772,7 +6693,6 @@
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz",
"integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==",
"dev": true,
"license": "MIT",
"dependencies": {
"thenify": ">= 3.1.0 < 4"
@ -6791,7 +6711,6 @@
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"is-number": "^7.0.0"
@ -6817,7 +6736,6 @@
"version": "0.1.13",
"resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz",
"integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==",
"dev": true,
"license": "Apache-2.0"
},
"node_modules/tslib": {
@ -6972,7 +6890,6 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
"dev": true,
"license": "MIT"
},
"node_modules/vaul": {
@ -7074,7 +6991,6 @@
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
"dev": true,
"license": "ISC",
"dependencies": {
"isexe": "^2.0.0"
@ -7100,7 +7016,6 @@
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
"integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"ansi-styles": "^6.1.0",
@ -7119,7 +7034,6 @@
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
"dev": true,
"license": "MIT",
"dependencies": {
"ansi-styles": "^4.0.0",
@ -7137,7 +7051,6 @@
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
@ -7147,14 +7060,12 @@
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
"dev": true,
"license": "MIT"
},
"node_modules/wrap-ansi-cjs/node_modules/string-width": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"dev": true,
"license": "MIT",
"dependencies": {
"emoji-regex": "^8.0.0",
@ -7169,7 +7080,6 @@
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"dev": true,
"license": "MIT",
"dependencies": {
"ansi-regex": "^5.0.1"
@ -7182,7 +7092,6 @@
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
"integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=12"
@ -7195,7 +7104,6 @@
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.6.0.tgz",
"integrity": "sha512-a6ae//JvKDEra2kdi1qzCyrJW/WZCgFi8ydDV+eXExl95t+5R+ijnqHJbz9tmMh8FUjx3iv2fCQ4dclAQlO2UQ==",
"dev": true,
"license": "ISC",
"bin": {
"yaml": "bin.mjs"

View File

@ -11,6 +11,7 @@
"preview": "vite preview"
},
"dependencies": {
"@google/generative-ai": "^0.24.1",
"@hookform/resolvers": "^3.9.0",
"@radix-ui/react-accordion": "^1.2.0",
"@radix-ui/react-alert-dialog": "^1.1.1",
@ -58,6 +59,7 @@
"recharts": "^2.12.7",
"sonner": "^1.5.0",
"tailwind-merge": "^2.5.2",
"tailwind-scrollbar-hide": "^4.0.0",
"tailwindcss-animate": "^1.0.7",
"vaul": "^0.9.3",
"zod": "^3.23.8"

View File

@ -18,6 +18,10 @@
filter: drop-shadow(0 0 2em #61dafbaa);
}
html, body, #root {
font-family: 'Quicksand', sans-serif;
}
@keyframes logo-spin {
from {
transform: rotate(0deg);

View File

@ -14,11 +14,13 @@ const App = () => (
<Toaster />
<Sonner />
<BrowserRouter>
<div className="font-sans">
<Routes>
<Route path="/" element={<Index />} />
{/* ADD ALL CUSTOM ROUTES ABOVE THE CATCH-ALL "*" ROUTE */}
<Route path="*" element={<NotFound />} />
</Routes>
</div>
</BrowserRouter>
</TooltipProvider>
</QueryClientProvider>

View File

@ -1,13 +1,15 @@
import React, { useState, useEffect } from 'react';
import React, { useState, useEffect, useRef } from 'react';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import TypingAnimation from './TypingAnimation';
import { getPromptContent } from '../utils/promptContent';
import { Plus, Send, Upload } from 'lucide-react';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from './ui/select';
interface ChatInterfaceProps {
onPromptSelect: (prompt: string, content: any) => void;
isExpanded: boolean;
onStartNewChat?: () => void;
}
const prompts = [
@ -21,9 +23,10 @@ const ChatInterface: React.FC<ChatInterfaceProps> = ({ onPromptSelect, isExpande
const [messages, setMessages] = useState<Array<{ text: string; isUser: boolean; isTyping?: boolean }>>([]);
const [inputValue, setInputValue] = useState('');
const [isThinking, setIsThinking] = useState(false);
const [chatKey, setChatKey] = useState(0);
const scrollAnchorRef = useRef<HTMLDivElement | null>(null);
const handlePromptClick = (prompt: string) => {
// Add user message
setMessages(prev => [...prev, { text: prompt, isUser: true }]);
setIsThinking(true);
@ -40,48 +43,47 @@ const ChatInterface: React.FC<ChatInterfaceProps> = ({ onPromptSelect, isExpande
const handleSendMessage = () => {
if (!inputValue.trim()) return;
const prompt = inputValue;
setInputValue('');
handlePromptClick(prompt);
};
const handleKeyPress = (e: React.KeyboardEvent) => {
if (e.key === 'Enter') {
handleSendMessage();
}
if (e.key === 'Enter') handleSendMessage();
};
// Listen for messages from left sidebar
useEffect(() => {
const handleLeftSidebarPrompt = (event: CustomEvent) => {
handlePromptClick(event.detail.prompt);
};
window.addEventListener('leftSidebarPrompt' as any, handleLeftSidebarPrompt);
return () => {
window.removeEventListener('leftSidebarPrompt' as any, handleLeftSidebarPrompt);
};
}, []);
useEffect(() => {
if (scrollAnchorRef.current) {
scrollAnchorRef.current.scrollIntoView({ behavior: 'smooth', block: 'end' });
}
}, [messages, isThinking]);
return (
<div className="flex flex-col h-full p-6">
<div className="flex flex-col h-screen max-h-screen overflow-hidden p-6">
{/* Hero Section */}
{messages.length === 0 && (
<div className={`flex-1 flex flex-col justify-center items-center text-center transition-all duration-500 ${
isExpanded ? 'max-w-4xl mx-auto' : 'max-w-2xl mx-auto'
}`}>
<div className="mb-8">
<h1 className="text-4xl md:text-6xl font-medium text-gray-900 dark:text-white mb-6 leading-tight">
Build an MCP server and become part of the new world
<h1 className="text-2xl md:text-6xl text-gray-900 dark:text-white mb-6 leading-tight">
Build an MCP server and become <span className='text-gray-700 dark:text-gray-300'>a part of the new world.</span>
</h1>
<p className="text-xl text-gray-600 dark:text-gray-300 mb-8">
Where AI chatbots are the modern interface
<p className="text-lg text-gray-600 dark:text-gray-300 mb-8">
Where AI chatbots are the modern interface.
</p>
</div>
{/* Glassmorphism card with prompts */}
<div className="w-full max-w-2xl p-8 rounded-2xl border border-gray-200/20 dark:border-gray-700/20 backdrop-blur-xl bg-white/10 dark:bg-black/10">
<h3 className="text-lg font-medium text-gray-900 dark:text-white mb-6">
How can I help you today?
@ -104,7 +106,11 @@ const ChatInterface: React.FC<ChatInterfaceProps> = ({ onPromptSelect, isExpande
{/* Chat Messages */}
{messages.length > 0 && (
<div className="flex-1 overflow-y-auto space-y-4 mb-6">
<div className="flex-1 w-full md:w-1/2 mx-auto mb-6 overflow-hidden">
<div
className="h-full overflow-y-auto space-y-4 scrollbar-hide pr-2"
ref={scrollAnchorRef}
>
{messages.map((message, index) => (
<div
key={index}
@ -113,7 +119,7 @@ const ChatInterface: React.FC<ChatInterfaceProps> = ({ onPromptSelect, isExpande
<div
className={`max-w-xs lg:max-w-md px-4 py-3 rounded-2xl ${
message.isUser
? 'bg-blue-500 text-white'
? 'dark:bg-gray-100/20 bg-gray-700/20 backdrop-blur-xl text-gray-900 dark:text-white'
: 'border border-gray-200/20 dark:border-gray-700/20 backdrop-blur-xl bg-white/10 dark:bg-black/10 text-gray-900 dark:text-white'
}`}
>
@ -125,7 +131,6 @@ const ChatInterface: React.FC<ChatInterfaceProps> = ({ onPromptSelect, isExpande
</div>
</div>
))}
{isThinking && (
<div className="flex justify-start">
<div className="max-w-xs lg:max-w-md px-4 py-3 rounded-2xl border border-gray-200/20 dark:border-gray-700/20 backdrop-blur-xl bg-white/10 dark:bg-black/10 text-gray-900 dark:text-white">
@ -135,30 +140,63 @@ const ChatInterface: React.FC<ChatInterfaceProps> = ({ onPromptSelect, isExpande
<div className="w-2 h-2 bg-gray-400 rounded-full animate-bounce" style={{ animationDelay: '0.1s' }}></div>
<div className="w-2 h-2 bg-gray-400 rounded-full animate-bounce" style={{ animationDelay: '0.2s' }}></div>
</div>
<span className="text-sm">AI is thinking...</span>
<span className="text-sm">Hmm good question...</span>
</div>
</div>
</div>
)}
{/* Anchor stays inside this container */}
<div ref={scrollAnchorRef} />
</div>
</div>
)}
{/* Input Area */}
<div className="border border-gray-200/20 dark:border-gray-700/20 backdrop-blur-xl bg-white/10 dark:bg-black/10 rounded-2xl p-4">
<div className="flex space-x-4">
<div className="w-full md:w-1/2 mx-auto border border-gray-200 dark:border-gray-700 backdrop-blur-xl bg-white/10 dark:bg-black/10 rounded-2xl px-4 py-3 space-y-3 pointer-events-auto">
{/* First Line: Text Input */}
<Input
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
onKeyPress={handleKeyPress}
onKeyDown={handleKeyPress}
placeholder="Ask me anything about MCP..."
className="flex-1 border-0 bg-transparent focus:ring-0 text-gray-900 dark:text-white placeholder-gray-500 dark:placeholder-gray-400"
className="border-0 bg-transparent focus:outline-none focus:ring-0 text-gray-900 dark:text-white placeholder-gray-500 dark:placeholder-gray-400"
/>
{/* Second Line: Dropdown + Upload + Send */}
<div className="flex items-center justify-between">
<div className="flex items-center gap-2">
{/* Dropdown */}
<Select>
<SelectTrigger className="w-[100px] h-9 bg-white/20 dark:bg-black/20 border-0 text-sm text-gray-900 dark:text-white">
<SelectValue placeholder="GPT-4.1" />
</SelectTrigger>
<SelectContent>
<SelectItem value="one">GPT-4o</SelectItem>
<SelectItem value="two">o3 Mini</SelectItem>
<SelectItem value="three">Gemini 2.5 Flash</SelectItem>
</SelectContent>
</Select>
{/* Upload Icon */}
<Button
type="button"
variant="ghost"
size="icon"
className="p-2 rounded-full hover:bg-gray-300 dark:hover:bg-gray-700 text-gray-900 dark:text-white"
aria-label="Upload"
>
<Plus className="w-5 h-5" />
</Button>
</div>
{/* Send Button */}
<Button
onClick={handleSendMessage}
disabled={!inputValue.trim()}
className="bg-blue-500 hover:bg-blue-600 text-white rounded-xl px-6"
className="h-10 w-10 flex items-center justify-center bg-gray-800 hover:bg-gray-900 dark:bg-gray-700 dark:hover:bg-gray-600 rounded-full text-white disabled:opacity-50 cursor-pointer disabled:cursor-not-allowed"
aria-label="Send"
>
Send
<Send className="w-4 h-4" />
</Button>
</div>
</div>

View File

@ -2,20 +2,34 @@
import React from 'react';
import { useTheme } from '../contexts/ThemeContext';
import { Button } from '@/components/ui/button';
import { FiSun, FiMoon } from 'react-icons/fi';
import { FiSun, FiMoon, FiMenu } from 'react-icons/fi';
const Header = () => {
interface HeaderProps {
onMenuClick?: () => void;
}
const Header: React.FC<HeaderProps> = ({ onMenuClick }) => {
const { isDark, toggleTheme } = useTheme();
return (
<header className="h-20 border-b border-gray-200/20 dark:border-gray-700/20 backdrop-blur-xl bg-white/10 dark:bg-black/10">
<div className="max-w-7xl mx-auto px-6 h-full flex items-center justify-between">
<div className="flex items-center space-x-4">
<div className="w-8 h-8 bg-gradient-to-br from-blue-500 to-purple-600 rounded-lg flex items-center justify-center">
{onMenuClick && (
<Button
variant="ghost"
size="sm"
onClick={onMenuClick}
className="md:hidden w-10 h-10 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors"
>
<FiMenu className="w-5 h-5" />
</Button>
)}
{/* <div className="w-8 h-8 bg-gradient-to-br from-blue-500 to-purple-600 rounded-lg flex items-center justify-center">
<span className="text-white font-bold text-sm">M</span>
</div>
<h1 className="text-xl font-semibold text-gray-900 dark:text-white">
MCP Platform
</div> */}
<h1 className="text-xl text-gray-900 dark:text-white">
Fastcode
</h1>
</div>

View File

@ -0,0 +1,104 @@
import { Button } from "@/components/ui/button"
import { ArrowRight, Play, MessageSquare, Zap, Sparkles } from "lucide-react"
const HeroSection = () => {
return (
<section id="hero" className="relative h-screen flex items-center justify-center overflow-hidden hero-gradient grain">
{/* Background grid */}
<div className="absolute inset-0 grid-glow opacity-30"></div>
{/* Floating elements */}
{/* <div className="absolute top-20 left-10 w-20 h-20 bg-foreground/5 rounded-full blur-xl animate-pulse"></div>
<div className="absolute bottom-20 right-10 w-32 h-32 bg-foreground/5 rounded-full blur-xl animate-pulse delay-700"></div>
<div className="absolute top-1/2 left-20 w-16 h-16 bg-foreground/5 rounded-full blur-xl animate-pulse delay-1000"></div> */}
<div className="relative z-10 max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 text-center">
<div className="max-w-4xl mx-auto">
{/* Badge */}
<div className="inline-flex items-center space-x-2 border border-yellow-500/50 glassmorphic rounded-full px-4 py-2 mb-8 hover-scale">
<Sparkles className="h-4 w-4 text-yellow-500" />
<span className="text-sm font-medium">Now in Beta</span>
</div>
{/* Main headline */}
<h1 className="text-2xl md:text-6xl font-light text-gray-900 dark:text-white mb-6 leading-tight">
<span className="text-foreground">
Monetize Your AI Ideas.
</span>
<br />
<span className="text-foreground/70">No Code Needed.</span>
</h1>
{/* Subtext */}
<p className="text-lg md:text-xl text-foreground/70 mb-12 max-w-3xl mx-auto leading-relaxed">
Create, deploy, and sell Everyday Series and MCPswhether you're a dev or not.
Turn your AI concepts into revenue streams with our powerful platform.
</p>
{/* CTA Buttons */}
<div className="flex flex-col sm:flex-row items-center justify-center space-y-4 sm:space-y-0 sm:space-x-6 mb-16">
<Button
size="lg"
className="bg-foreground text-background hover:bg-foreground/90 px-8 py-4 text-lg font-semibold btn-hover-scale group"
>
<Zap className="h-5 w-5 mr-2 text-yellow-500 group-hover:animate-pulse" />
Start Building
<ArrowRight className="h-5 w-5 ml-2 group-hover:translate-x-1 transition-transform" />
</Button>
<Button
variant="outline"
size="lg"
className="glassmorphic px-8 py-4 text-lg font-semibold btn-outline-fill group border-foreground/20"
>
<Play className="h-5 w-5 mr-2" />
See Examples
</Button>
</div>
{/* ChatGPT-style interface preview */}
<div className="relative max-w-4xl mx-auto hover-scale dark:border rounded-lg">
<div className="glassmorphic rounded-2xl p-6 shadow-2xl">
<div className="flex items-center space-x-3 mb-4">
<div className="flex space-x-2">
<div className="w-3 h-3 bg-red-500 rounded-full"></div>
<div className="w-3 h-3 bg-yellow-500 rounded-full"></div>
<div className="w-3 h-3 bg-green-500 rounded-full"></div>
</div>
<div className="text-sm text-foreground/60">MCP Chat Interface</div>
</div>
<div className="space-y-4">
<div className="flex items-start space-x-3">
<div className="w-8 h-8 bg-foreground/10 rounded-full flex items-center justify-center">
<MessageSquare className="h-4 w-4 text-foreground" />
</div>
<div className="flex-1 glassmorphic rounded-lg p-4">
<p className="text-sm text-left text-foreground/80">
"Create a trading bot that monitors crypto prices and executes trades based on technical indicators"
</p>
</div>
</div>
<div className="flex items-start space-x-3">
<div className="w-8 h-8 bg-foreground/10 rounded-full flex items-center justify-center">
<Zap className="h-4 w-4 text-foreground" />
</div>
<div className="flex-1 glassmorphic rounded-lg p-4">
<p className="text-sm text-left text-foreground/80">
Perfect! I've created your trading bot MCP. It's now live and earning $2.50 per execution. <br />
<span className="text-foreground font-semibold">Revenue this month: $847</span>
</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
)
}
export default HeroSection

View File

@ -1,11 +1,13 @@
import React from 'react';
import React, { useRef, useEffect } from 'react';
import { Button } from '@/components/ui/button';
import { useTheme } from '../contexts/ThemeContext';
import { FiMenu, FiX, FiHelpCircle, FiUsers, FiDollarSign, FiZap, FiExternalLink } from 'react-icons/fi';
import { FiMenu, FiX, FiHelpCircle, FiUsers, FiDollarSign, FiZap, FiExternalLink, FiMoon, FiSun } from 'react-icons/fi';
import { LucideCodeXml } from 'lucide-react';
import { useNavigate } from "react-router-dom";
interface LeftSidebarProps {
onPromptSelect: (prompt: string, content: any) => void;
onStartNewChat?: () => void; // Add this prop
}
const suggestedQuestions = [
@ -15,11 +17,41 @@ const suggestedQuestions = [
{ text: "What can you help me with?", icon: FiZap },
];
const LeftSidebar: React.FC<LeftSidebarProps> = ({ onPromptSelect }) => {
const navLinks = [
{ text: "Home", icon: FiHelpCircle, to: "#home" },
{ text: "MCPs", icon: FiUsers, to: "#mcps" },
{ text: "Monetize", icon: FiDollarSign, to: "#monetize" },
];
const LeftSidebar: React.FC<LeftSidebarProps> = ({ onPromptSelect, onStartNewChat }) => {
const { sidebarOpen, setSidebarOpen } = useTheme();
const { isDark, toggleTheme } = useTheme();
const sidebarRef = useRef<HTMLDivElement>(null);
const navigate = useNavigate();
// Close sidebar on outside click
useEffect(() => {
if (!sidebarOpen) return;
const handleClickOutside = (event: MouseEvent) => {
if (
sidebarRef.current &&
!sidebarRef.current.contains(event.target as Node)
) {
setSidebarOpen(false);
}
};
document.addEventListener('mousedown', handleClickOutside);
return () => {
document.removeEventListener('mousedown', handleClickOutside);
};
}, [sidebarOpen, setSidebarOpen]);
const handlePromptClick = (prompt: string) => {
// This will trigger the same logic as in ChatInterface
// Dispatch a custom event to notify ChatInterface
const event = new CustomEvent('leftSidebarPrompt', { detail: { prompt } });
window.dispatchEvent(event);
// Trigger the same logic as in ChatInterface
onPromptSelect(prompt, null);
};
@ -38,62 +70,93 @@ const LeftSidebar: React.FC<LeftSidebarProps> = ({ onPromptSelect }) => {
{/* Sidebar */}
<div
className={`fixed left-0 top-20 h-[calc(100vh-80px)] w-72 transform transition-transform duration-500 ease-in-out z-40 ${
ref={sidebarRef}
className={`fixed left-0 top-0 bg-clip-padding backdrop-filter backdrop-blur-sm bg-opacity-10 border border-gray-200/20 dark:border-gray-700/20 h-screen w-72 transform transition-transform duration-500 ease-in-out z-40 ${
sidebarOpen ? 'translate-x-0' : '-translate-x-full'
}`}
>
<div className="h-full border-r border-gray-200/10 dark:border-gray-700/10 backdrop-blur-xl bg-white/90 dark:bg-black/90">
<div className="p-6 h-full flex flex-col">
{/* Header */}
<div className="flex items-center justify-between mb-8">
<h2 className="text-lg font-medium text-gray-900 dark:text-white">
Quick Start
</h2>
<div className="h-full border-r border-gray-200/20 dark:border-gray-700/20 bg-clip-padding backdrop-filter backdrop-blur-sm bg-white/20 dark:bg-black/20 bg-opacity-40 flex flex-col">
{/* Top Section: Logo, Navigation, Theme Toggle */}
<div className="p-6 pb-2 flex items-cneter justify-between">
{/* Logo */}
<div className="flex items-center gap-2">
{/* <img src="/logo.svg" alt="Logo" className="w-8 h-8" /> */}
<LucideCodeXml />
<span className="text-lg text-gray-900 dark:text-white">FastCode</span>
</div>
{/* Theme Toggle */}
<Button
variant="ghost"
onClick={() => setSidebarOpen(false)}
className="w-8 h-8 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors"
size="sm"
onClick={toggleTheme}
className="w-10 h-10 rounded-full border border-gray-200/20 dark:border-gray-700/20 backdrop-blur-sm bg-white/10 dark:bg-black/10 hover:bg-white/20 dark:hover:bg-black/20 transition-all duration-300"
aria-label="Toggle theme"
>
<FiX className="w-4 h-4" />
{isDark ? <FiSun className="w-4 h-4" /> : <FiMoon className="w-4 h-4" />}
</Button>
</div>
{/* Suggested Questions */}
<div className="flex-1 space-y-6">
<div>
<h3 className="text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider mb-4">
Explore Features
{/* Nav menu */}
{/* <div className="px-6">
<h3 className="text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider mb-4 mt-4">
Navigation
</h3>
{navLinks.map((nav, index) => (
<button
key={index}
onClick={() => navigate(nav.to)}
className="w-full flex justify-start p-4 h-auto text-left border-0 bg-transparent text-gray-500 hover:text-black transition-colors duration-200 group"
>
<nav.icon className="w-4 h-4 mr-3 text-gray-400 group-hover:text-black dark:group-hover:text-white transition-colors" />
<span className="text-sm text-gray-500 dark:text-gray-400 group-hover:text-black dark:group-hover:text-white transition-colors">
{nav.text}
</span>
</button>
))}
</div> */}
{/* Main Section: Suggested Questions & Start New Chat */}
<div className="flex-1 flex flex-col justify-between">
<div className="px-6">
<h3 className="text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider mb-4 mt-4">
Quick Start
</h3>
<div className="space-y-2">
{suggestedQuestions.map((question, index) => (
<Button
<button
key={index}
variant="ghost"
onClick={() => handlePromptClick(question.text)}
className="w-full justify-start p-4 h-auto text-left rounded-xl border-0 bg-transparent hover:bg-gray-50 dark:hover:bg-gray-800/50 transition-all duration-200 group"
className="w-full flex justify-start p-4 h-auto text-left border-0 bg-transparent text-gray-500 hover:text-black transition-colors duration-200 group"
>
<question.icon className="w-4 h-4 mr-3 text-gray-400 group-hover:text-gray-600 dark:group-hover:text-gray-300 transition-colors" />
<span className="text-sm text-gray-700 dark:text-gray-300 group-hover:text-gray-900 dark:group-hover:text-white transition-colors">
<question.icon className="w-4 h-4 mr-3 text-gray-400 group-hover:text-black dark:group-hover:text-white transition-colors" />
<span className="text-sm text-gray-500 dark:text-gray-400 group-hover:text-black dark:group-hover:text-white transition-colors">
{question.text}
</span>
</Button>
</button>
))}
</div>
{/* Start New Chat Button */}
<Button
variant="outline"
className="w-full mt-6"
onClick={onStartNewChat}
>
Start New Chat
</Button>
</div>
{/* Website Link */}
<div className="pt-6 border-t border-gray-200/20 dark:border-gray-700/20">
{/* Bottom Section: Visit Website */}
<div className="p-6 mt-auto">
<h3 className="text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider mb-4">
Resources
</h3>
<Button
variant="ghost"
asChild
className="w-full justify-start p-4 h-auto text-left rounded-xl border-0 bg-transparent hover:bg-gray-50 dark:hover:bg-gray-800/50 transition-all duration-200 group"
className="w-full justify-start p-4 h-auto text-left border-0 bg-transparent text-gray-500 hover:text-black dark:text-gray-400 dark:hover:text-white transition-colors duration-200 group"
>
<a href="https://yourdomain.com" target="_blank" rel="noopener noreferrer">
<FiExternalLink className="w-4 h-4 mr-3 text-gray-400 group-hover:text-gray-600 dark:group-hover:text-gray-300 transition-colors" />
<span className="text-sm text-gray-700 dark:text-gray-300 group-hover:text-gray-900 dark:group-hover:text-white transition-colors">
<FiExternalLink className="w-4 h-4 mr-3 text-gray-400 group-hover:text-black dark:group-hover:text-white transition-colors" />
<span className="text-sm text-gray-500 dark:text-gray-400 group-hover:text-black dark:group-hover:text-white transition-colors">
Visit Website
</span>
</a>
@ -102,7 +165,6 @@ const LeftSidebar: React.FC<LeftSidebarProps> = ({ onPromptSelect }) => {
</div>
</div>
</div>
</div>
</>
);
};

View File

@ -0,0 +1,127 @@
import { Button } from "@/components/ui/button"
import { Code, Cpu, DollarSign, Zap, ArrowRight, Box } from "lucide-react"
const MCPSection = () => {
return (
<section id="mcps" className="relative flex mt-10 items-center justify-center overflow-hidden hero-gradient bg-transparent grain">
<div className="relative z-10 max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="text-center mb-16">
<div className="inline-flex items-center space-x-2 border border-yellow-500/50 glassmorphic rounded-full px-4 py-2 mb-6">
<Box className="h-4 w-4 text-yellow-500" />
<span className="text-sm font-medium">Monetizable Code Packages</span>
</div>
<h2 className="text-2xl md:text-3xl mb-6">
What is an <span className="text-foreground/70">MCP</span>?
</h2>
<p className="text-lg text-foreground/70 max-w-3xl mx-auto leading-relaxed">
MCP = a wrapper on an API that works with LLMs. Think of it as a packaged AI behavior
ready to be deployed or sold. No complex infrastructure needed.
</p>
</div>
<div className="grid md:grid-cols-2 lg:grid-cols-3 gap-8 mb-10">
{/* Simple to Create */}
<div className="glassmorphic rounded-2xl p-6 hover:scale-105 border border-foreground/20 transition-transform duration-300">
<div className="w-12 h-12 bg-foreground/10 rounded-xl flex items-center justify-center mb-6">
<Code className="h-6 w-6 text-foreground" />
</div>
<h3 className="text-xl font-semibold mb-4">Simple to Create</h3>
<p className="text-sm text-foreground/70 mb-2">
Use our visual builder or write custom code. MCPs wrap your logic into LLM-compatible packages.
</p>
<div className="glassmorphic bg-foreground/10 rounded-lg p-4 text-sm font-mono">
<span className="text-green-800">// Example MCP</span><br/>
<span className="text-red-500">function</span> <span className="text-foreground/80">weatherBot</span>()<br/>
<span className="text-foreground/60"> Returns: Live weather data</span>
</div>
</div>
{/* Easy to Deploy */}
<div className="glassmorphic rounded-2xl p-6 hover:scale-105 border border-foreground/20 transition-transform duration-300">
<div className="w-12 h-12 bg-foreground/10 rounded-xl flex items-center justify-center mb-6">
<Cpu className="h-6 w-6 text-foreground" />
</div>
<h3 className="text-xl font-semibold mb-4">Easy to Deploy</h3>
<p className="text-sm text-foreground/70 mb-6">
One-click deployment to our global network. Your MCP becomes instantly available to LLMs worldwide.
</p>
<div className="flex items-center space-x-2 text-xs">
<div className="w-2 h-2 bg-green-500 rounded-full animate-pulse"></div>
<span className="text-foreground/70">Status: Live & Earning</span>
</div>
</div>
{/* Ready to Monetize */}
<div className="glassmorphic rounded-2xl p-6 hover:scale-105 border border-foreground/20 transition-transform duration-300">
<div className="w-12 h-12 bg-foreground/10 rounded-xl flex items-center justify-center mb-6">
<DollarSign className="h-6 w-6 text-foreground" />
</div>
<h3 className="text-xl font-semibold mb-4">Ready to Monetize</h3>
<p className="text-sm text-foreground/70 mb-6">
Set your pricing, track usage, and get paid automatically. Turn your AI ideas into recurring revenue.
</p>
<div className="space-y-2 text-xs mx-6 ml-auto">
<div className="flex justify-between">
<span className="text-foreground/70">Per-use pricing:</span>
<span className="text-yellow-500">$0.01 - $10.00</span>
</div>
<div className="flex justify-between">
<span className="text-foreground/70">Monthly revenue:</span>
<span className="text-yellow-500">$500 - $5000+</span>
</div>
</div>
</div>
</div>
{/* Example MCPs */}
<div className="glassmorphic rounded-2xl p-8 mb-12">
<h3 className="text-2xl mb-6 text-center">Popular MCP Examples</h3>
<div className="grid md:grid-cols-3 gap-6">
<div className="text-center p-6 rounded-xl bg-foreground/5">
<div className="w-12 h-12 bg-foreground/10 rounded-full flex items-center justify-center mx-auto mb-3">
<Code className="h-6 w-6 text-foreground" />
</div>
<h4 className="font-semibold mb-2">Code Generator</h4>
<p className="text-sm text-foreground/70">Generates clean, documented code in any language</p>
<div className="text-xs text-foreground/60 mt-2">$2.50/use 1.2k uses this month</div>
</div>
<div className="text-center p-6 rounded-xl bg-foreground/5">
<div className="w-12 h-12 bg-foreground/10 rounded-full flex items-center justify-center mx-auto mb-3">
<Cpu className="h-6 w-6 text-foreground" />
</div>
<h4 className="font-semibold mb-2">Data Analyzer</h4>
<p className="text-sm text-foreground/70">Converts raw data into actionable insights</p>
<div className="text-xs text-foreground/60 mt-2">$5.00/use 800 uses this month</div>
</div>
<div className="text-center p-6 rounded-xl bg-foreground/5">
<div className="w-12 h-12 bg-foreground/10 rounded-full flex items-center justify-center mx-auto mb-3">
<DollarSign className="h-6 w-6 text-foreground" />
</div>
<h4 className="font-semibold mb-2">Content Creator</h4>
<p className="text-sm text-foreground/70">Writes engaging content for any platform</p>
<div className="text-xs text-foreground/60 mt-2">$1.00/use 2.1k uses this month</div>
</div>
</div>
</div>
<div className="text-center">
<Button
size="lg"
className="bg-foreground text-background hover:bg-foreground/90 px-8 py-4 text-md font-normal btn-hover-scale group"
>
<Zap className="h-5 w-5 mr-2" />
Create Your First MCP
<ArrowRight className="h-5 w-5 ml-2 group-hover:translate-x-1 transition-transform" />
</Button>
</div>
</div>
</section>
)
}
export default MCPSection

View File

@ -0,0 +1,208 @@
import { Button } from "@/components/ui/button"
import { DollarSign, TrendingUp, Zap, Globe, ArrowRight, BarChart3 } from "lucide-react"
const MonetizeSection = () => {
return (
<section id="monetize" className="py-24 relative overflow-hidden">
{/* Background grid pattern */}
<div className="absolute inset-0 grid-glow opacity-20"></div>
<div className="relative z-10 max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="text-center mb-16">
<div className="inline-flex items-center space-x-2 border border-yellow-500/50 glassmorphic rounded-full px-4 py-2 mb-6">
<DollarSign className="h-4 w-4 text-yellow-500" />
<span className="text-sm font-medium">Revenue Streams</span>
</div>
<h2 className="text-4xl md:text-5xl mb-6">
<span className="text-foreground/70">Monetize</span> Your Creations
</h2>
<p className="text-xl text-foreground/70 max-w-3xl mx-auto leading-relaxed">
Turn your MCPs into profitable APIs. Create disposable apps that live and die per use.
Build the future of AI-powered commerce.
</p>
</div>
{/* Revenue Models */}
<div className="grid md:grid-cols-3 gap-8 mb-16">
<div className="glassmorphic rounded-2xl p-8 hover-lift">
<div className="w-12 h-12 bg-foreground/10 rounded-xl flex items-center justify-center mb-6">
<Zap className="h-6 w-6 text-foreground" />
</div>
<h3 className="text-xl mb-4">Per-Use Pricing</h3>
<p className="text-sm text-foreground/70 mb-6">
Charge users each time they access your MCP. Perfect for high-value, specialized tools.
</p>
<div className="space-y-2 text-sm">
<div className="flex justify-between">
<span className="text-foreground/60">Typical range:</span>
<span className="font-semibold">$0.01 - $50</span>
</div>
<div className="flex justify-between">
<span className="text-foreground/60">Revenue share:</span>
<span className="font-semibold text-foreground">85% to you</span>
</div>
</div>
</div>
<div className="glassmorphic rounded-2xl p-8 hover-lift">
<div className="w-12 h-12 bg-foreground/10 rounded-xl flex items-center justify-center mb-6">
<BarChart3 className="h-6 w-6 text-foreground" />
</div>
<h3 className="text-xl mb-4">Subscription Series</h3>
<p className="text-sm text-foreground/70 mb-6">
Monthly recurring revenue from your Everyday Series. Build loyal audiences that pay regularly.
</p>
<div className="space-y-2 text-sm">
<div className="flex justify-between">
<span className="text-foreground/60">Monthly pricing:</span>
<span className="font-semibold">$2.99 - $99</span>
</div>
<div className="flex justify-between">
<span className="text-foreground/60">Revenue share:</span>
<span className="font-semibold text-foreground">90% to you</span>
</div>
</div>
</div>
<div className="glassmorphic rounded-2xl p-8 hover-lift">
<div className="w-12 h-12 bg-foreground/10 rounded-xl flex items-center justify-center mb-6">
<Globe className="h-6 w-6 text-foreground" />
</div>
<h3 className="text-xl mb-4">Disposable Apps</h3>
<p className="text-sm text-foreground/70 mb-6">
Lightweight apps that serve one purpose, then disappear. Zero maintenance, pure profit.
</p>
<div className="space-y-2 text-sm">
<div className="flex justify-between">
<span className="text-foreground/60">App lifespan:</span>
<span className="font-semibold">1 use - 24 hours</span>
</div>
<div className="flex justify-between">
<span className="text-foreground/60">Revenue share:</span>
<span className="font-semibold text-foreground">85% to you</span>
</div>
</div>
</div>
</div>
{/* Network Effect Visualization */}
<div className="glassmorphic rounded-3xl p-8 mb-16">
<h3 className="text-2xl text-center mb-8">The MCP Network Effect</h3>
<div className="relative max-w-4xl mx-auto">
{/* Central hub */}
<div className="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 w-16 h-16 bg-foreground/10 rounded-full flex items-center justify-center z-10">
<span className="text-foreground font-bold text-sm">YOU</span>
</div>
{/* Connection lines */}
<div className="absolute inset-0 flex items-center justify-center z-1">
<div className="w-96 h-96 relative z-1">
{/* Animated connection lines */}
{[0, 45, 90, 135, 180, 225, 270, 315].map((angle, index) => (
<div
key={angle}
className="absolute w-40 h-0.5 bg-gradient-to-r from-foreground/20 to-transparent origin-left"
style={{
transform: `rotate(${angle}deg)`,
top: '50%',
left: '50%',
animationDelay: `${index * 0.2}s`
}}
></div>
))}
</div>
</div>
{/* Network nodes */}
<div className="grid grid-cols-4 gap-8 items-center justify-items-center py-8">
<div className="glassmorphic rounded-xl p-4 text-center hover-lift">
<div className="w-8 h-8 bg-foreground/10 rounded-full flex items-center justify-center mx-auto mb-2">
<Zap className="h-4 w-4 text-foreground" />
</div>
<div className="text-sm font-medium">AI Agents</div>
<div className="text-xs text-foreground/60">+$2.4k/mo</div>
</div>
<div className="glassmorphic rounded-xl p-4 text-center hover-lift">
<div className="w-8 h-8 bg-foreground/10 rounded-full flex items-center justify-center mx-auto mb-2">
<Globe className="h-4 w-4 text-foreground" />
</div>
<div className="text-sm font-medium">Users</div>
<div className="text-xs text-foreground/60">8.2k active</div>
</div>
<div className="glassmorphic rounded-xl p-4 text-center hover-lift">
<div className="w-8 h-8 bg-foreground/10 rounded-full flex items-center justify-center mx-auto mb-2">
<BarChart3 className="h-4 w-4 text-foreground" />
</div>
<div className="text-sm font-medium">Apps</div>
<div className="text-xs text-foreground/60">150+ deployed</div>
</div>
<div className="glassmorphic rounded-xl p-4 text-center hover-lift">
<div className="w-8 h-8 bg-foreground/10 rounded-full flex items-center justify-center mx-auto mb-2">
<DollarSign className="h-4 w-4 text-foreground" />
</div>
<div className="text-sm font-medium">Revenue</div>
<div className="text-xs text-foreground/60">$45k total</div>
</div>
<div className="glassmorphic rounded-xl p-4 text-center hover-lift">
<div className="w-8 h-8 bg-foreground/10 rounded-full flex items-center justify-center mx-auto mb-2">
<TrendingUp className="h-4 w-4 text-foreground" />
</div>
<div className="text-sm font-medium">APIs</div>
<div className="text-xs text-foreground/60">24/7 uptime</div>
</div>
<div className="glassmorphic rounded-xl p-4 text-center hover-lift">
<div className="w-8 h-8 bg-foreground/10 rounded-full flex items-center justify-center mx-auto mb-2">
<ArrowRight className="h-4 w-4 text-foreground" />
</div>
<div className="text-sm font-medium">Analytics</div>
<div className="text-xs text-foreground/60">Real-time</div>
</div>
<div className="glassmorphic rounded-xl p-4 text-center hover-lift">
<div className="w-8 h-8 bg-foreground/10 rounded-full flex items-center justify-center mx-auto mb-2">
<Globe className="h-4 w-4 text-foreground" />
</div>
<div className="text-sm font-medium">Global CDN</div>
<div className="text-xs text-foreground/60">Edge compute</div>
</div>
<div className="glassmorphic rounded-xl p-4 text-center hover-lift">
<div className="w-8 h-8 bg-foreground/10 rounded-full flex items-center justify-center mx-auto mb-2">
<ArrowRight className="h-4 w-4 text-foreground" />
</div>
<div className="text-sm font-medium">Scaling</div>
<div className="text-xs text-foreground/60">Auto-scale</div>
</div>
</div>
</div>
<p className="text-center text-foreground/70 mt-8 max-w-2xl mx-auto">
Your MCPs become nodes in a global AI network. Every connection multiplies your earning potential.
Build once, earn everywhere.
</p>
</div>
<div className="text-center">
<Button
size="lg"
className="bg-foreground text-background hover:bg-foreground/90 px-8 py-4 text-lg font-semibold hover-lift group"
>
<TrendingUp className="h-5 w-5 mr-2 text-green-300 dark:text-green-700" />
Start Earning Today
<ArrowRight className="h-5 w-5 ml-2 group-hover:translate-x-1 transition-transform" />
</Button>
</div>
</div>
</section>
)
}
export default MonetizeSection

View File

@ -12,11 +12,11 @@ interface SidebarPanelProps {
const SidebarPanel: React.FC<SidebarPanelProps> = ({ isOpen, content, onClose }) => {
return (
<div
className={`fixed right-0 top-20 h-[calc(100vh-80px)] w-1/2 transform transition-transform duration-500 ease-in-out z-40 ${
className={`fixed right-0 top-10 h-[calc(100vh-80px)] w-2/5 rounded-3xl shadow-md transform transition-transform duration-500 ease-in-out z-40 ${
isOpen ? 'translate-x-0' : 'translate-x-full'
}`}
>
<div className="h-full border-l border-gray-200/10 dark:border-gray-700/10 backdrop-blur-xl bg-white/90 dark:bg-black/90">
<div className="h-full rounded-3xl border-l border-gray-200/10 dark:border-gray-700/10 backdrop-blur-xl bg-white/90 dark:bg-black/90">
<div className="p-8 h-full overflow-y-auto">
<div className="flex items-center justify-between mb-8">
<h2 className="text-2xl font-medium text-gray-900 dark:text-white">

View File

@ -0,0 +1,50 @@
import React, { useEffect, useState } from 'react';
import { generateResponse } from '@/services/geminiService';
interface DynamicContentProps {
content: any;
}
const DynamicContent: React.FC<DynamicContentProps> = ({ content }) => {
const [geminiAnswer, setGeminiAnswer] = useState<string | null>(null);
const [loading, setLoading] = useState(false);
useEffect(() => {
const fetchGemini = async () => {
if (content?.type === 'gemini' && content.prompt) {
setLoading(true);
const res = await generateResponse(content.prompt, []);
setGeminiAnswer(res.message);
setLoading(false);
}
};
fetchGemini();
}, [content]);
if (!content) return null;
if (content.type === 'gemini') {
return (
<div className="p-6">
<h3 className="text-lg font-semibold mb-4">Gemini Answer</h3>
{loading ? (
<div className="text-gray-500">Loading...</div>
) : (
<div className="text-gray-900 dark:text-white whitespace-pre-line">{geminiAnswer}</div>
)}
</div>
);
}
// If content is a React node/component, render it
if (React.isValidElement(content)) return content;
// Fallback: render as text
return (
<div className="p-6 text-gray-900 dark:text-white">
{typeof content === 'string' ? content : JSON.stringify(content)}
</div>
);
};
export default DynamicContent;

View File

@ -8,7 +8,7 @@ const Input = React.forwardRef<HTMLInputElement, React.ComponentProps<"input">>(
<input
type={type}
className={cn(
"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-base ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-base file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
className
)}
ref={ref}

83
src/hooks/useChat.ts Normal file
View File

@ -0,0 +1,83 @@
import { useState, useCallback } from 'react';
import { generateResponse, isQuestionUnknown } from '../services/geminiService';
export interface Message {
id: string;
role: 'user' | 'model';
content: string;
isUnknown?: boolean;
timestamp: number;
}
export const useChat = () => {
const [messages, setMessages] = useState<Message[]>([]);
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const addMessage = useCallback((message: Omit<Message, 'id' | 'timestamp'>) => {
const newMessage: Message = {
...message,
id: Date.now().toString(),
timestamp: Date.now(),
};
setMessages(prev => [...prev, newMessage]);
return newMessage;
}, []);
const sendMessage = useCallback(async (content: string) => {
if (!content.trim()) return;
const userMessage = addMessage({
role: 'user',
content,
});
setIsLoading(true);
setError(null);
try {
const chatHistory = messages
.filter(m => m.role === 'user' || m.role === 'model')
.map(m => ({
role: m.role,
parts: m.content,
}));
const response = await generateResponse(content, chatHistory);
if (response.success) {
const isUnknown = isQuestionUnknown(response.message);
addMessage({
role: 'model',
content: response.message,
isUnknown,
});
} else {
throw new Error(response.message);
}
} catch (err) {
console.error('Error in sendMessage:', err);
setError(err instanceof Error ? err.message : 'An unknown error occurred');
addMessage({
role: 'model',
content: 'Sorry, I encountered an error while processing your request. Please try again later.',
isUnknown: true,
});
} finally {
setIsLoading(false);
}
}, [addMessage, messages]);
const clearChat = useCallback(() => {
setMessages([]);
setError(null);
}, []);
return {
messages,
isLoading,
error,
sendMessage,
clearChat,
};
};

View File

@ -1,4 +1,3 @@
import React, { useState } from 'react';
import Header from '../components/Header';
import ChatInterface from '../components/ChatInterface';
@ -6,10 +5,21 @@ import SidebarPanel from '../components/SidebarPanel';
import LeftSidebar from '../components/LeftSidebar';
import { ThemeProvider } from '../contexts/ThemeContext';
import { getPromptContent } from '../utils/promptContent';
import { FiInfo } from 'react-icons/fi'; // Add this import
import HeroSection from '@/components/HeroSection';
import MCPSection from '@/components/MCPSection';
import MonetizeSection from '@/components/MonetizeSection';
const Index = () => {
const [selectedPrompt, setSelectedPrompt] = useState<string | null>(null);
const [sidebarContent, setSidebarContent] = useState<any>(null);
const [chatKey, setChatKey] = useState(0);
const handleStartNewChat = () => {
setChatKey(prev => prev + 1); // This will remount ChatInterface and reset its state
setSelectedPrompt(null);
setSidebarContent(null);
};
const handlePromptSelect = (prompt: string, content?: any) => {
setSelectedPrompt(prompt);
@ -23,25 +33,44 @@ const Index = () => {
setSidebarContent(null);
};
// Add a default info content if needed
const defaultInfoContent = {
title: "Chatbot Side Panel",
description: "Welcome to MCP Verse Spark! Here you can chat with our AI, explore features, and learn more about MCP."
};
return (
<ThemeProvider>
<div className="min-h-screen bg-gradient-to-br from-white via-gray-50 to-gray-100 dark:from-black dark:via-gray-900 dark:to-black transition-all duration-500">
<Header />
<div className="bg-gradient-to-br from-white via-gray-50 to-gray-100 dark:from-black dark:via-black dark:to-black transition-all duration-500">
{/* <Header /> */}
{/* CHAT INTERFACE */}
<div className="flex h-[calc(100vh-80px)] relative">
{/* Left Sidebar */}
<LeftSidebar onPromptSelect={handlePromptSelect} />
<LeftSidebar onPromptSelect={handlePromptSelect} onStartNewChat={handleStartNewChat} />
{/* Main Chat Interface */}
<div className={`transition-all duration-500 ease-in-out ${
selectedPrompt ? 'w-1/2 ml-0' : 'w-full ml-0'
}`}>
<ChatInterface
key={chatKey} // Add key to force remount on new chat
onPromptSelect={handlePromptSelect}
isExpanded={!selectedPrompt}
/>
</div>
{/* Sidebar Open Icon */}
{!selectedPrompt && (
<button
onClick={() => handlePromptSelect('info', defaultInfoContent)}
className="fixed top-24 right-4 z-50 w-10 h-10 rounded-xl border border-gray-200/20 dark:border-gray-700/20 backdrop-blur-md bg-white/80 dark:bg-black/80 hover:bg-white/90 dark:hover:bg-black/90 transition-all duration-300 shadow-lg flex items-center justify-center"
aria-label="Open Info Sidebar"
>
<FiInfo className="w-5 h-5 text-gray-700 dark:text-gray-200" />
</button>
)}
{/* Right Sliding Sidebar Panel */}
<SidebarPanel
isOpen={!!selectedPrompt}
@ -51,10 +80,39 @@ const Index = () => {
</div>
{/* Subtle light leaks */}
<div className="fixed inset-0 pointer-events-none overflow-hidden">
{/* <div className="fixed inset-0 pointer-events-none overflow-hidden">
<div className="absolute -top-1/2 -right-1/2 w-full h-full bg-gradient-radial from-blue-500/5 via-transparent to-transparent dark:from-blue-400/10"></div>
<div className="absolute -bottom-1/2 -left-1/2 w-full h-full bg-gradient-radial from-purple-500/5 via-transparent to-transparent dark:from-purple-400/10"></div>
</div> */}
{/* Authentic light leaks with warmth and blur */}
{/* <div className="fixed inset-0 pointer-events-none overflow-hidden z-0">
<div className="absolute top-[10%] left-[5%] w-[300px] h-[300px] bg-red-400 opacity-20 rounded-full mix-blend-screen blur-3xl animate-pulse-slow" />
<div className="absolute bottom-[15%] right-[10%] w-[250px] h-[250px] bg-yellow-300 opacity-15 rounded-full mix-blend-screen blur-2xl animate-pulse-slower" />
<div className="absolute top-[30%] right-[20%] w-[200px] h-[200px] bg-pink-400 opacity-10 rounded-full mix-blend-screen blur-3xl animate-pulse" />
<div className="absolute bottom-[20%] left-[25%] w-[280px] h-[280px] bg-orange-300 opacity-20 rounded-full mix-blend-screen blur-2xl animate-pulse" />
</div> */}
{/* Realistic Film Camera Light Leaks */}
<div className="fixed inset-0 pointer-events-none overflow-hidden z-0">
{/* Horizontal streak from left */}
<div className="absolute left-0 top-1/4 w-[600px] h-[200px] bg-gradient-to-r from-red-400/30 via-orange-300/20 to-transparent blur-3xl rotate-[-5deg] skew-y-6 mix-blend-screen" />
{/* Vertical burn from bottom */}
<div className="absolute bottom-0 left-1/3 w-[300px] h-[580px] bg-gradient-to-t from-yellow-300/20 via-pink-400/10 to-transparent blur-3xl rotate-12 mix-blend-screen" />
{/* Angled streak from top right */}
<div className="absolute top-0 right-0 w-[400px] h-[300px] bg-gradient-to-bl from-red-500/20 via-orange-300/10 to-transparent blur-2xl -rotate-12 mix-blend-screen" />
{/* Blobby irregular light spot */}
<div className="absolute bottom-[10%] right-[20%] w-[350px] h-[250px] bg-pink-300/15 rounded-3xl blur-[100px] rotate-[18deg] mix-blend-screen" />
</div>
<HeroSection />
<MCPSection />
<MonetizeSection />
</div>
</ThemeProvider>
);

View File

@ -0,0 +1,71 @@
import { GoogleGenerativeAI } from '@google/generative-ai';
// Initialize the Gemini API with your API key
const genAI = new GoogleGenerativeAI(process.env.NEXT_PUBLIC_GEMINI_API_KEY || '');
const SYSTEM_PROMPT = `You are an AI assistant that helps users navigate and answer queries of a website which promotes the monetization of MCPs.`
export const generateResponse = async (prompt: string, chatHistory: Array<{role: 'user' | 'model', parts: string}>) => {
try {
// Get the Gemini Pro model
const model = genAI.getGenerativeModel({ model: 'gemini-pro' });
// Format chat history for the API
const chat = model.startChat({
history: [
{
role: 'user',
parts: [{ text: SYSTEM_PROMPT }],
},
{
role: 'model',
parts: [{ text: 'I understand. I will follow these guidelines when responding to questions, especially when I don\'t have complete information.' }],
},
...chatHistory.map(msg => ({
role: msg.role === 'user' ? 'user' : 'model',
parts: [{ text: msg.parts }],
})),
],
generationConfig: {
maxOutputTokens: 1000,
temperature: 0.7,
},
});
// Send the message and get the response
const result = await chat.sendMessage(prompt);
const response = await result.response;
const text = response.text();
return {
success: true,
message: text,
};
} catch (error) {
console.error('Error generating response:', error);
return {
success: false,
message: 'Sorry, I encountered an error while processing your request. Please try again later.'
};
}
};
export const isQuestionUnknown = (response: string): boolean => {
// Simple check for phrases that might indicate the model doesn't know the answer
const unknownPhrases = [
'i don\'t know',
'i\'m not sure',
'i don\'t have that information',
'i don\'t have specific information',
'i don\'t have access to',
'i don\'t have the capability',
'i don\'t have enough information',
'i can\'t provide',
'i\'m unable to',
'i don\'t have the ability',
];
return unknownPhrases.some(phrase =>
response.toLowerCase().includes(phrase)
);
};

View File

@ -64,6 +64,9 @@ export default {
ring: 'hsl(var(--sidebar-ring))'
}
},
fontFamily: {
sans: ['Quicksand', 'ui-sans-serif', 'system-ui'],
},
borderRadius: {
lg: 'var(--radius)',
md: 'calc(var(--radius) - 2px)',
@ -88,13 +91,48 @@ export default {
to: {
height: '0'
}
}
},
flicker: {
'0%, 100%': { opacity: '0.15' },
'50%': { opacity: '0.25' },
},
pulse: {
'0%, 100%': { opacity: '1' },
'50%': { opacity: '0.5' },
},
'pulse-slow': {
'0%, 100%': { opacity: '1' },
'50%': { opacity: '0.7' },
},
'pulse-slower': {
'0%, 100%': { opacity: '1' },
'50%': { opacity: '0.8' },
},
driftX: {
'0%': { transform: 'translateX(0px) rotate(-5deg)' },
'50%': { transform: 'translateX(20px) rotate(-4deg)' },
'100%': { transform: 'translateX(0px) rotate(-5deg)' },
},
driftY: {
'0%': { transform: 'translateY(0px) rotate(12deg)' },
'50%': { transform: 'translateY(-20px) rotate(10deg)' },
'100%': { transform: 'translateY(0px) rotate(12deg)' },
},
},
animation: {
'accordion-down': 'accordion-down 0.2s ease-out',
'accordion-up': 'accordion-up 0.2s ease-out'
'accordion-up': 'accordion-up 0.2s ease-out',
flicker: 'flicker 5s ease-in-out infinite',
driftX: 'driftX 10s ease-in-out infinite',
driftY: 'driftY 12s ease-in-out infinite',
pulse: 'pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite',
'pulse-slow': 'pulse-slow 3s cubic-bezier(0.4, 0, 0.6, 1) infinite',
'pulse-slower': 'pulse-slower 4s cubic-bezier(0.4, 0, 0.6, 1) infinite',
}
}
},
plugins: [require("tailwindcss-animate")],
plugins: [
require('tailwind-scrollbar-hide'),
require("tailwindcss-animate")
],
} satisfies Config;