diff --git a/.github/workflows/aws-cd.yml b/.github/workflows/aws-cd.yml index f03aeb4..921ccc7 100644 --- a/.github/workflows/aws-cd.yml +++ b/.github/workflows/aws-cd.yml @@ -40,6 +40,9 @@ jobs: npm run build env: VITE_STAGE: ${{ github.ref_name }} + VITE_API_URL: ${{vars.API_URL}} + VITE_BUCKET_NAME: ${{vars.BUCKET_NAME}} + VITE_API_CHAT_URL: ${{vars.API_CHAT_URL}} - name: Setup envs run: | echo AWS_REGION=${{ vars.AWS_REGION }} >> $GITHUB_ENV diff --git a/index.html b/index.html index a4a211e..b5d4932 100644 --- a/index.html +++ b/index.html @@ -1,5 +1,5 @@ - + diff --git a/package-lock.json b/package-lock.json index b49ce14..b76baa3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,20 +8,33 @@ "name": "knowly", "version": "1.0.0", "dependencies": { + "@hookform/resolvers": "^5.0.1", "@lottiefiles/dotlottie-react": "^0.13.5", + "@radix-ui/react-checkbox": "^1.3.2", + "@radix-ui/react-dialog": "^1.1.14", "@radix-ui/react-dropdown-menu": "^2.1.14", - "@radix-ui/react-slot": "^1.2.2", + "@radix-ui/react-label": "^2.1.7", + "@radix-ui/react-popover": "^1.1.14", + "@radix-ui/react-select": "^2.2.5", + "@radix-ui/react-separator": "^1.1.7", + "@radix-ui/react-slot": "^1.2.3", + "@radix-ui/react-tooltip": "^1.2.7", "@tailwindcss/vite": "^4.1.5", "@tanstack/react-query": "^5.75.1", "axios": "^1.9.0", "class-variance-authority": "^0.7.1", + "date-fns": "^4.1.0", "lucide-react": "^0.511.0", "motion": "^12.10.1", "react": "^19.0.0", "react-dom": "^19.0.0", + "react-hook-form": "^7.56.4", + "react-hot-toast": "^2.5.2", "react-icons": "^5.5.0", "react-router-dom": "^7.5.3", - "tailwindcss": "^4.1.5" + "tailwindcss": "^4.1.5", + "uuidv4": "^6.2.13", + "zod": "^3.25.28" }, "devDependencies": { "@tanstack/eslint-plugin-query": "^5.74.7", @@ -904,6 +917,18 @@ "integrity": "sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==", "license": "MIT" }, + "node_modules/@hookform/resolvers": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-5.0.1.tgz", + "integrity": "sha512-u/+Jp83luQNx9AdyW2fIPGY6Y7NG68eN2ZW8FOJYL+M0i4s49+refdJdOp/A9n9HFQtQs3HIDHQvX3ZET2o7YA==", + "license": "MIT", + "dependencies": { + "@standard-schema/utils": "^0.3.0" + }, + "peerDependencies": { + "react-hook-form": "^7.55.0" + } + }, "node_modules/@humanwhocodes/config-array": { "version": "0.13.0", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", @@ -1086,6 +1111,12 @@ "url": "https://opencollective.com/pkgr" } }, + "node_modules/@radix-ui/number": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.1.tgz", + "integrity": "sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==", + "license": "MIT" + }, "node_modules/@radix-ui/primitive": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.2.tgz", @@ -1115,6 +1146,59 @@ } } }, + "node_modules/@radix-ui/react-checkbox": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-1.3.2.tgz", + "integrity": "sha512-yd+dI56KZqawxKZrJ31eENUwqc1QSqg4OZ15rybGjF2ZNwMO+wCyHzAVLRp9qoYJf7kYy0YpZ2b0JCzJ42HZpA==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-presence": "1.1.4", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-previous": "1.1.1", + "@radix-ui/react-use-size": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-checkbox/node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-collection": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.6.tgz", @@ -1141,6 +1225,24 @@ } } }, + "node_modules/@radix-ui/react-collection/node_modules/@radix-ui/react-slot": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.2.tgz", + "integrity": "sha512-y7TBO4xN4Y94FvcWIOIh18fM4R1A8S4q1jhoz4PNzOoHsFcN8pogcFmZrTYAm4F9VRUrWP/Mw7xSKybIeRI+CQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-compose-refs": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz", @@ -1171,6 +1273,141 @@ } } }, + "node_modules/@radix-ui/react-dialog": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.14.tgz", + "integrity": "sha512-+CpweKjqpzTmwRwcYECQcNYbI8V9VSQt0SNFKeEBLgfucbsLssU6Ppq7wUdNXEGb573bMjFhVjKVll8rmV6zMw==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-dismissable-layer": "1.1.10", + "@radix-ui/react-focus-guards": "1.1.2", + "@radix-ui/react-focus-scope": "1.1.7", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-presence": "1.1.4", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.6.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-dismissable-layer": { + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.10.tgz", + "integrity": "sha512-IM1zzRV4W3HtVgftdQiiOmA0AdJlCtMLe00FXaHwgt3rAnNsIyDqshvkIW3hj/iu5hu8ERP7KIYki6NkqDxAwQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-escape-keydown": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-focus-scope": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.7.tgz", + "integrity": "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-portal": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.9.tgz", + "integrity": "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-direction": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.1.tgz", @@ -1178,25 +1415,759 @@ "license": "MIT", "peerDependencies": { "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dismissable-layer": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.9.tgz", + "integrity": "sha512-way197PiTvNp+WBP7svMJasHl+vibhWGQDb6Mgf5mhEWJkgb85z7Lfl9TUdkqpWsf8GRNmoopx9ZxCyDzmgRMQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-primitive": "2.1.2", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-escape-keydown": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dropdown-menu": { + "version": "2.1.14", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.14.tgz", + "integrity": "sha512-lzuyNjoWOoaMFE/VC5FnAAYM16JmQA8ZmucOXtlhm2kKR5TSU95YLAueQ4JYuRmUJmBvSqXaVFGIfuukybwZJQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-menu": "2.1.14", + "@radix-ui/react-primitive": "2.1.2", + "@radix-ui/react-use-controllable-state": "1.2.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-focus-guards": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.2.tgz", + "integrity": "sha512-fyjAACV62oPV925xFCrH8DR5xWhg9KYtJT4s3u54jxp+L/hbpTY2kIeEFFbFe+a/HCE94zGQMZLIpVTPVZDhaA==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-focus-scope": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.6.tgz", + "integrity": "sha512-r9zpYNUQY+2jWHWZGyddQLL9YHkM/XvSFHVcWs7bdVuxMAnCwTAuy6Pf47Z4nw7dYcUou1vg/VgjjrrH03VeBw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-primitive": "2.1.2", + "@radix-ui/react-use-callback-ref": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-id": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.1.tgz", + "integrity": "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-label": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-2.1.7.tgz", + "integrity": "sha512-YT1GqPSL8kJn20djelMX7/cTRp/Y9w5IZHvfxQTVHrOqa2yMl7i/UfMqKRU5V7mEyKTrUVgJXhNQPVCG8PBLoQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-label/node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-menu": { + "version": "2.1.14", + "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.1.14.tgz", + "integrity": "sha512-0zSiBAIFq9GSKoSH5PdEaQeRB3RnEGxC+H2P0egtnKoKKLNBH8VBHyVO6/jskhjAezhOIplyRUj7U2lds9A+Yg==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-collection": "1.1.6", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-dismissable-layer": "1.1.9", + "@radix-ui/react-focus-guards": "1.1.2", + "@radix-ui/react-focus-scope": "1.1.6", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-popper": "1.2.6", + "@radix-ui/react-portal": "1.1.8", + "@radix-ui/react-presence": "1.1.4", + "@radix-ui/react-primitive": "2.1.2", + "@radix-ui/react-roving-focus": "1.1.9", + "@radix-ui/react-slot": "1.2.2", + "@radix-ui/react-use-callback-ref": "1.1.1", + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.6.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-menu/node_modules/@radix-ui/react-slot": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.2.tgz", + "integrity": "sha512-y7TBO4xN4Y94FvcWIOIh18fM4R1A8S4q1jhoz4PNzOoHsFcN8pogcFmZrTYAm4F9VRUrWP/Mw7xSKybIeRI+CQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-popover": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.1.14.tgz", + "integrity": "sha512-ODz16+1iIbGUfFEfKx2HTPKizg2MN39uIOV8MXeHnmdd3i/N9Wt7vU46wbHsqA0xoaQyXVcs0KIlBdOA2Y95bw==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-dismissable-layer": "1.1.10", + "@radix-ui/react-focus-guards": "1.1.2", + "@radix-ui/react-focus-scope": "1.1.7", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-popper": "1.2.7", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-presence": "1.1.4", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.6.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-arrow": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.7.tgz", + "integrity": "sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-dismissable-layer": { + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.10.tgz", + "integrity": "sha512-IM1zzRV4W3HtVgftdQiiOmA0AdJlCtMLe00FXaHwgt3rAnNsIyDqshvkIW3hj/iu5hu8ERP7KIYki6NkqDxAwQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-escape-keydown": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-focus-scope": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.7.tgz", + "integrity": "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-popper": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.7.tgz", + "integrity": "sha512-IUFAccz1JyKcf/RjB552PlWwxjeCJB8/4KxT7EhBHOJM+mN7LdW+B3kacJXILm32xawcMMjb2i0cIZpo+f9kiQ==", + "license": "MIT", + "dependencies": { + "@floating-ui/react-dom": "^2.0.0", + "@radix-ui/react-arrow": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-layout-effect": "1.1.1", + "@radix-ui/react-use-rect": "1.1.1", + "@radix-ui/react-use-size": "1.1.1", + "@radix-ui/rect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-portal": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.9.tgz", + "integrity": "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-popper": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.6.tgz", + "integrity": "sha512-7iqXaOWIjDBfIG7aq8CUEeCSsQMLFdn7VEE8TaFz704DtEzpPHR7w/uuzRflvKgltqSAImgcmxQ7fFX3X7wasg==", + "license": "MIT", + "dependencies": { + "@floating-ui/react-dom": "^2.0.0", + "@radix-ui/react-arrow": "1.1.6", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-primitive": "2.1.2", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-layout-effect": "1.1.1", + "@radix-ui/react-use-rect": "1.1.1", + "@radix-ui/react-use-size": "1.1.1", + "@radix-ui/rect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-portal": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.8.tgz", + "integrity": "sha512-hQsTUIn7p7fxCPvao/q6wpbxmCwgLrlz+nOrJgC+RwfZqWY/WN+UMqkXzrtKbPrF82P43eCTl3ekeKuyAQbFeg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.2", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-presence": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.4.tgz", + "integrity": "sha512-ueDqRbdc4/bkaQT3GIpLQssRlFgWaL/U2z/S31qRwwLWoxHLgry3SIfCwhxeQNbirEUXFa+lq3RL3oBYXtcmIA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-primitive": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.2.tgz", + "integrity": "sha512-uHa+l/lKfxuDD2zjN/0peM/RhhSmRjr5YWdk/37EnSv1nJ88uvG85DPexSm8HdFQROd2VdERJ6ynXbkCFi+APw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-primitive/node_modules/@radix-ui/react-slot": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.2.tgz", + "integrity": "sha512-y7TBO4xN4Y94FvcWIOIh18fM4R1A8S4q1jhoz4PNzOoHsFcN8pogcFmZrTYAm4F9VRUrWP/Mw7xSKybIeRI+CQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-roving-focus": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.9.tgz", + "integrity": "sha512-ZzrIFnMYHHCNqSNCsuN6l7wlewBEq0O0BCSBkabJMFXVO51LRUTq71gLP1UxFvmrXElqmPjA5VX7IqC9VpazAQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-collection": "1.1.6", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-primitive": "2.1.2", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-controllable-state": "1.2.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-select": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.2.5.tgz", + "integrity": "sha512-HnMTdXEVuuyzx63ME0ut4+sEMYW6oouHWNGUZc7ddvUWIcfCva/AMoqEW/3wnEllriMWBa0RHspCYnfCWJQYmA==", + "license": "MIT", + "dependencies": { + "@radix-ui/number": "1.1.1", + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-collection": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-dismissable-layer": "1.1.10", + "@radix-ui/react-focus-guards": "1.1.2", + "@radix-ui/react-focus-scope": "1.1.7", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-popper": "1.2.7", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-layout-effect": "1.1.1", + "@radix-ui/react-use-previous": "1.1.1", + "@radix-ui/react-visually-hidden": "1.2.3", + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.6.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-arrow": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.7.tgz", + "integrity": "sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-collection": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.7.tgz", + "integrity": "sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-dismissable-layer": { + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.10.tgz", + "integrity": "sha512-IM1zzRV4W3HtVgftdQiiOmA0AdJlCtMLe00FXaHwgt3rAnNsIyDqshvkIW3hj/iu5hu8ERP7KIYki6NkqDxAwQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-escape-keydown": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-focus-scope": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.7.tgz", + "integrity": "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-popper": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.7.tgz", + "integrity": "sha512-IUFAccz1JyKcf/RjB552PlWwxjeCJB8/4KxT7EhBHOJM+mN7LdW+B3kacJXILm32xawcMMjb2i0cIZpo+f9kiQ==", + "license": "MIT", + "dependencies": { + "@floating-ui/react-dom": "^2.0.0", + "@radix-ui/react-arrow": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-layout-effect": "1.1.1", + "@radix-ui/react-use-rect": "1.1.1", + "@radix-ui/react-use-size": "1.1.1", + "@radix-ui/rect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { "optional": true + }, + "@types/react-dom": { + "optional": true } } }, - "node_modules/@radix-ui/react-dismissable-layer": { + "node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-portal": { "version": "1.1.9", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.9.tgz", - "integrity": "sha512-way197PiTvNp+WBP7svMJasHl+vibhWGQDb6Mgf5mhEWJkgb85z7Lfl9TUdkqpWsf8GRNmoopx9ZxCyDzmgRMQ==", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.9.tgz", + "integrity": "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.2", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-primitive": "2.1.2", - "@radix-ui/react-use-callback-ref": "1.1.1", - "@radix-ui/react-use-escape-keydown": "1.1.1" + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", @@ -1213,19 +2184,13 @@ } } }, - "node_modules/@radix-ui/react-dropdown-menu": { - "version": "2.1.14", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.14.tgz", - "integrity": "sha512-lzuyNjoWOoaMFE/VC5FnAAYM16JmQA8ZmucOXtlhm2kKR5TSU95YLAueQ4JYuRmUJmBvSqXaVFGIfuukybwZJQ==", + "node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.2", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-menu": "2.1.14", - "@radix-ui/react-primitive": "2.1.2", - "@radix-ui/react-use-controllable-state": "1.2.2" + "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", @@ -1242,30 +2207,36 @@ } } }, - "node_modules/@radix-ui/react-focus-guards": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.2.tgz", - "integrity": "sha512-fyjAACV62oPV925xFCrH8DR5xWhg9KYtJT4s3u54jxp+L/hbpTY2kIeEFFbFe+a/HCE94zGQMZLIpVTPVZDhaA==", + "node_modules/@radix-ui/react-separator": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-separator/-/react-separator-1.1.7.tgz", + "integrity": "sha512-0HEb8R9E8A+jZjvmFCy/J4xhbXy3TV+9XSnGJ3KvTtjlIUy/YQ/p6UYZvi7YbeoeXdyU9+Y3scizK6hkY37baA==", "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.3" + }, "peerDependencies": { "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { "optional": true + }, + "@types/react-dom": { + "optional": true } } }, - "node_modules/@radix-ui/react-focus-scope": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.6.tgz", - "integrity": "sha512-r9zpYNUQY+2jWHWZGyddQLL9YHkM/XvSFHVcWs7bdVuxMAnCwTAuy6Pf47Z4nw7dYcUou1vg/VgjjrrH03VeBw==", + "node_modules/@radix-ui/react-separator/node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", "license": "MIT", "dependencies": { - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-primitive": "2.1.2", - "@radix-ui/react-use-callback-ref": "1.1.1" + "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", @@ -1282,13 +2253,13 @@ } } }, - "node_modules/@radix-ui/react-id": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.1.tgz", - "integrity": "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==", + "node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", "license": "MIT", "dependencies": { - "@radix-ui/react-use-layout-effect": "1.1.1" + "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", @@ -1300,30 +2271,24 @@ } } }, - "node_modules/@radix-ui/react-menu": { - "version": "2.1.14", - "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.1.14.tgz", - "integrity": "sha512-0zSiBAIFq9GSKoSH5PdEaQeRB3RnEGxC+H2P0egtnKoKKLNBH8VBHyVO6/jskhjAezhOIplyRUj7U2lds9A+Yg==", + "node_modules/@radix-ui/react-tooltip": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.2.7.tgz", + "integrity": "sha512-Ap+fNYwKTYJ9pzqW+Xe2HtMRbQ/EeWkj2qykZ6SuEV4iS/o1bZI5ssJbk4D2r8XuDuOBVz/tIx2JObtuqU+5Zw==", "license": "MIT", "dependencies": { "@radix-ui/primitive": "1.1.2", - "@radix-ui/react-collection": "1.1.6", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-direction": "1.1.1", - "@radix-ui/react-dismissable-layer": "1.1.9", - "@radix-ui/react-focus-guards": "1.1.2", - "@radix-ui/react-focus-scope": "1.1.6", + "@radix-ui/react-dismissable-layer": "1.1.10", "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-popper": "1.2.6", - "@radix-ui/react-portal": "1.1.8", + "@radix-ui/react-popper": "1.2.7", + "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.4", - "@radix-ui/react-primitive": "2.1.2", - "@radix-ui/react-roving-focus": "1.1.9", - "@radix-ui/react-slot": "1.2.2", - "@radix-ui/react-use-callback-ref": "1.1.1", - "aria-hidden": "^1.2.4", - "react-remove-scroll": "^2.6.3" + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-visually-hidden": "1.2.3" }, "peerDependencies": { "@types/react": "*", @@ -1340,22 +2305,13 @@ } } }, - "node_modules/@radix-ui/react-popper": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.6.tgz", - "integrity": "sha512-7iqXaOWIjDBfIG7aq8CUEeCSsQMLFdn7VEE8TaFz704DtEzpPHR7w/uuzRflvKgltqSAImgcmxQ7fFX3X7wasg==", + "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-arrow": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.7.tgz", + "integrity": "sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==", "license": "MIT", "dependencies": { - "@floating-ui/react-dom": "^2.0.0", - "@radix-ui/react-arrow": "1.1.6", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-primitive": "2.1.2", - "@radix-ui/react-use-callback-ref": "1.1.1", - "@radix-ui/react-use-layout-effect": "1.1.1", - "@radix-ui/react-use-rect": "1.1.1", - "@radix-ui/react-use-size": "1.1.1", - "@radix-ui/rect": "1.1.1" + "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", @@ -1372,14 +2328,17 @@ } } }, - "node_modules/@radix-ui/react-portal": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.8.tgz", - "integrity": "sha512-hQsTUIn7p7fxCPvao/q6wpbxmCwgLrlz+nOrJgC+RwfZqWY/WN+UMqkXzrtKbPrF82P43eCTl3ekeKuyAQbFeg==", + "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-dismissable-layer": { + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.10.tgz", + "integrity": "sha512-IM1zzRV4W3HtVgftdQiiOmA0AdJlCtMLe00FXaHwgt3rAnNsIyDqshvkIW3hj/iu5hu8ERP7KIYki6NkqDxAwQ==", "license": "MIT", "dependencies": { - "@radix-ui/react-primitive": "2.1.2", - "@radix-ui/react-use-layout-effect": "1.1.1" + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-escape-keydown": "1.1.1" }, "peerDependencies": { "@types/react": "*", @@ -1396,14 +2355,22 @@ } } }, - "node_modules/@radix-ui/react-presence": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.4.tgz", - "integrity": "sha512-ueDqRbdc4/bkaQT3GIpLQssRlFgWaL/U2z/S31qRwwLWoxHLgry3SIfCwhxeQNbirEUXFa+lq3RL3oBYXtcmIA==", + "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-popper": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.7.tgz", + "integrity": "sha512-IUFAccz1JyKcf/RjB552PlWwxjeCJB8/4KxT7EhBHOJM+mN7LdW+B3kacJXILm32xawcMMjb2i0cIZpo+f9kiQ==", "license": "MIT", "dependencies": { + "@floating-ui/react-dom": "^2.0.0", + "@radix-ui/react-arrow": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-use-layout-effect": "1.1.1" + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-layout-effect": "1.1.1", + "@radix-ui/react-use-rect": "1.1.1", + "@radix-ui/react-use-size": "1.1.1", + "@radix-ui/rect": "1.1.1" }, "peerDependencies": { "@types/react": "*", @@ -1420,13 +2387,14 @@ } } }, - "node_modules/@radix-ui/react-primitive": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.2.tgz", - "integrity": "sha512-uHa+l/lKfxuDD2zjN/0peM/RhhSmRjr5YWdk/37EnSv1nJ88uvG85DPexSm8HdFQROd2VdERJ6ynXbkCFi+APw==", + "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-portal": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.9.tgz", + "integrity": "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==", "license": "MIT", "dependencies": { - "@radix-ui/react-slot": "1.2.2" + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", @@ -1443,21 +2411,13 @@ } } }, - "node_modules/@radix-ui/react-roving-focus": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.9.tgz", - "integrity": "sha512-ZzrIFnMYHHCNqSNCsuN6l7wlewBEq0O0BCSBkabJMFXVO51LRUTq71gLP1UxFvmrXElqmPjA5VX7IqC9VpazAQ==", + "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.2", - "@radix-ui/react-collection": "1.1.6", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-direction": "1.1.1", - "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-primitive": "2.1.2", - "@radix-ui/react-use-callback-ref": "1.1.1", - "@radix-ui/react-use-controllable-state": "1.2.2" + "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", @@ -1474,24 +2434,6 @@ } } }, - "node_modules/@radix-ui/react-slot": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.2.tgz", - "integrity": "sha512-y7TBO4xN4Y94FvcWIOIh18fM4R1A8S4q1jhoz4PNzOoHsFcN8pogcFmZrTYAm4F9VRUrWP/Mw7xSKybIeRI+CQ==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-compose-refs": "1.1.2" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, "node_modules/@radix-ui/react-use-callback-ref": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.1.tgz", @@ -1577,6 +2519,21 @@ } } }, + "node_modules/@radix-ui/react-use-previous": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.1.tgz", + "integrity": "sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-use-rect": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.1.tgz", @@ -1613,6 +2570,52 @@ } } }, + "node_modules/@radix-ui/react-visually-hidden": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.2.3.tgz", + "integrity": "sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-visually-hidden/node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, "node_modules/@radix-ui/rect": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.1.tgz", @@ -1879,6 +2882,12 @@ "win32" ] }, + "node_modules/@standard-schema/utils": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@standard-schema/utils/-/utils-0.3.0.tgz", + "integrity": "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==", + "license": "MIT" + }, "node_modules/@tailwindcss/node": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.5.tgz", @@ -2257,6 +3266,12 @@ "@types/react": "^19.0.0" } }, + "node_modules/@types/uuid": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", + "integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==", + "license": "MIT" + }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "8.32.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.32.0.tgz", @@ -2996,7 +4011,6 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "devOptional": true, "license": "MIT" }, "node_modules/data-view-buffer": { @@ -3053,6 +4067,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/date-fns": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-4.1.0.tgz", + "integrity": "sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/kossnocorp" + } + }, "node_modules/debug": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", @@ -4191,6 +5215,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/goober": { + "version": "2.1.16", + "resolved": "https://registry.npmjs.org/goober/-/goober-2.1.16.tgz", + "integrity": "sha512-erjk19y1U33+XAMe1VTvIONHYoSqE4iS7BYUZfHaqeohLmnC0FdxEh7rQU+6MZ4OajItzjZFSRtVANrQwNq6/g==", + "license": "MIT", + "peerDependencies": { + "csstype": "^3.0.10" + } + }, "node_modules/gopd": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", @@ -5828,6 +6861,39 @@ "react": "^19.1.0" } }, + "node_modules/react-hook-form": { + "version": "7.56.4", + "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.56.4.tgz", + "integrity": "sha512-Rob7Ftz2vyZ/ZGsQZPaRdIefkgOSrQSPXfqBdvOPwJfoGnjwRJUs7EM7Kc1mcoDv3NOtqBzPGbcMB8CGn9CKgw==", + "license": "MIT", + "engines": { + "node": ">=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/react-hook-form" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17 || ^18 || ^19" + } + }, + "node_modules/react-hot-toast": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/react-hot-toast/-/react-hot-toast-2.5.2.tgz", + "integrity": "sha512-Tun3BbCxzmXXM7C+NI4qiv6lT0uwGh4oAfeJyNOjYUejTsm35mK9iCaYLGv8cBz9L5YxZLx/2ii7zsIwPtPUdw==", + "license": "MIT", + "dependencies": { + "csstype": "^3.1.3", + "goober": "^2.1.16" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "react": ">=16", + "react-dom": ">=16" + } + }, "node_modules/react-icons": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.5.0.tgz", @@ -6893,6 +7959,26 @@ } } }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/uuidv4": { + "version": "6.2.13", + "resolved": "https://registry.npmjs.org/uuidv4/-/uuidv4-6.2.13.tgz", + "integrity": "sha512-AXyzMjazYB3ovL3q051VLH06Ixj//Knx7QnUSi1T//Ie3io6CpsPu9nVMOx5MoLWh6xV0B9J0hIaxungxXUbPQ==", + "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", + "license": "MIT", + "dependencies": { + "@types/uuid": "8.3.4", + "uuid": "8.3.2" + } + }, "node_modules/vite": { "version": "6.3.5", "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.5.tgz", @@ -7134,6 +8220,15 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/zod": { + "version": "3.25.28", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.28.tgz", + "integrity": "sha512-/nt/67WYKnr5by3YS7LroZJbtcCBurDKKPBPWWzaxvVCGuG/NOsiKkrjoOhI8mJ+SQUXEbUzeB3S+6XDUEEj7Q==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } } } } diff --git a/package.json b/package.json index 119302a..e4cfbd2 100644 --- a/package.json +++ b/package.json @@ -4,26 +4,39 @@ "version": "1.0.0", "type": "module", "scripts": { - "dev": "vite", + "dev": "vite --open", "build": "tsc -b && vite build", "lint": "eslint src --fix", "preview": "vite preview" }, "dependencies": { + "@hookform/resolvers": "^5.0.1", "@lottiefiles/dotlottie-react": "^0.13.5", + "@radix-ui/react-checkbox": "^1.3.2", + "@radix-ui/react-dialog": "^1.1.14", "@radix-ui/react-dropdown-menu": "^2.1.14", - "@radix-ui/react-slot": "^1.2.2", + "@radix-ui/react-label": "^2.1.7", + "@radix-ui/react-popover": "^1.1.14", + "@radix-ui/react-select": "^2.2.5", + "@radix-ui/react-separator": "^1.1.7", + "@radix-ui/react-slot": "^1.2.3", + "@radix-ui/react-tooltip": "^1.2.7", "@tailwindcss/vite": "^4.1.5", "@tanstack/react-query": "^5.75.1", "axios": "^1.9.0", "class-variance-authority": "^0.7.1", + "date-fns": "^4.1.0", "lucide-react": "^0.511.0", "motion": "^12.10.1", "react": "^19.0.0", "react-dom": "^19.0.0", + "react-hook-form": "^7.56.4", + "react-hot-toast": "^2.5.2", "react-icons": "^5.5.0", "react-router-dom": "^7.5.3", - "tailwindcss": "^4.1.5" + "tailwindcss": "^4.1.5", + "uuidv4": "^6.2.13", + "zod": "^3.25.28" }, "devDependencies": { "@tanstack/eslint-plugin-query": "^5.74.7", diff --git a/src/assets/berti.jfif b/src/assets/berti.jfif deleted file mode 100644 index 9d4012e..0000000 Binary files a/src/assets/berti.jfif and /dev/null differ diff --git a/src/assets/izabel.jfif b/src/assets/izabel.jfif deleted file mode 100644 index d4307c1..0000000 Binary files a/src/assets/izabel.jfif and /dev/null differ diff --git a/src/assets/julia.jfif b/src/assets/julia.jfif deleted file mode 100644 index f43acb3..0000000 Binary files a/src/assets/julia.jfif and /dev/null differ diff --git a/src/assets/rubio.jfif b/src/assets/rubio.jfif deleted file mode 100644 index effc2fa..0000000 Binary files a/src/assets/rubio.jfif and /dev/null differ diff --git a/src/assets/sakamoto.jfif b/src/assets/sakamoto.jfif deleted file mode 100644 index 696105e..0000000 Binary files a/src/assets/sakamoto.jfif and /dev/null differ diff --git a/src/domain/knowledge-base.ts b/src/domain/knowledge-base.ts new file mode 100644 index 0000000..793a789 --- /dev/null +++ b/src/domain/knowledge-base.ts @@ -0,0 +1,25 @@ +import { STATUS } from '@/shared/enums/status' + +export type KnowledgeBase = { + id: string + name: string + displayName: string + description: string + createdAt: Date + updatedAt: Date + status: STATUS + files: KnowledgeBaseFile[] + totalSizeMB: number + keys: KnowledgeBaseKey[] +} + +export type KnowledgeBaseFile = { + fileName: string + sizeMB: number + url: string +} + +export type KnowledgeBaseKey = { + kbKey: string + kbKeyAlias: string +} diff --git a/src/features/docs/pages/about-project.tsx b/src/features/docs/pages/about-project.tsx new file mode 100644 index 0000000..6e49858 --- /dev/null +++ b/src/features/docs/pages/about-project.tsx @@ -0,0 +1,57 @@ +import { motion } from 'framer-motion' +import { h1, h2, p } from '@/shared/components/typography' + +export function AboutProjectPage() { + return ( + + {h1({ children: 'Sobre o Projeto' })} + + {h2({ children: 'Por que criamos o Knowly?' })} + {p({ + children: ( + <> + A inteligência artificial está mudando a forma como empresas + trabalham, trazendo mais agilidade e eficiência para o dia a dia. + Mas, para a maioria dos negócios, usar IA ainda é caro e complicado: + exige conhecimento técnico, tempo e investimento alto em tecnologia. + + ) + })} + {p({ + children: ( + <> + O Knowly nasceu para simplificar esse cenário. Queremos que qualquer + empresa consiga aproveitar o poder dos grandes modelos de linguagem + para responder dúvidas, organizar informações e automatizar tarefas, + sem precisar se preocupar com detalhes técnicos ou infraestrutura. + + ) + })} + {p({ + children: ( + <> + Nossa plataforma permite que você envie seus próprios documentos e, + em poucos cliques, já tenha uma base de conhecimento inteligente + pronta para ser usada no seu atendimento, site ou operação interna. + Tudo isso com segurança, praticidade e custos acessíveis. + + ) + })} + {p({ + children: ( + <> + O objetivo é ajudar empresas a inovar, ganhar tempo e focar no que + realmente importa: crescer e atender melhor seus clientes, usando IA + de verdade no dia a dia. + + ) + })} + + ) +} + +export default AboutProjectPage diff --git a/src/features/docs/pages/foundation-models.tsx b/src/features/docs/pages/foundation-models.tsx new file mode 100644 index 0000000..407c874 --- /dev/null +++ b/src/features/docs/pages/foundation-models.tsx @@ -0,0 +1,129 @@ +import { motion } from 'framer-motion' +import { h1, h2, p, ul, li } from '@/shared/components/typography' + +export function FoundationModelsPage() { + return ( + + {h1({ children: 'Modelos de Fundação AWS' })} + + {h2({ children: 'O que são modelos de fundação?' })} + {p({ + children: ( + <> + Modelos de fundação são inteligências artificiais treinadas para + entender e gerar textos, responder perguntas, resumir informações e + até criar conteúdos. Eles servem como base para várias aplicações de + IA, desde chatbots até análise de documentos. + + ) + })} + + {h2({ children: 'Principais modelos disponíveis na AWS' })} + {ul({ + children: ( + <> + {li({ + children: ( + <> + Amazon Titan: Modelo versátil para tarefas do + dia a dia, como responder perguntas, resumir textos e + organizar informações. É uma ótima escolha para quem busca + equilíbrio entre custo e desempenho. + + ) + })} + {li({ + children: ( + <> + Anthropic Claude: Ideal para conversas mais + longas, respostas detalhadas e situações que exigem mais + segurança e controle. Muito usado em chatbots avançados e + assistentes virtuais. + + ) + })} + {li({ + children: ( + <> + AI21 Labs: Especialista em geração de textos + criativos, artigos, e até mesmo conteúdos técnicos. Indicado + para quem precisa de textos mais elaborados ou criativos. + + ) + })} + {li({ + children: ( + <> + Cohere: Focado em análise de linguagem, + classificação de textos e extração de informações. Bom para + automação de processos e análise de grandes volumes de dados. + + ) + })} + + ) + })} + + {h2({ children: 'Quando usar cada modelo?' })} + {ul({ + children: ( + <> + {li({ + children: ( + <> + Precisa de respostas rápidas e gerais? Use o{' '} + Amazon Titan. + + ) + })} + {li({ + children: ( + <> + + Vai criar um chatbot ou assistente virtual que precisa + conversar bastante? + {' '} + O Claude é uma ótima opção. + + ) + })} + {li({ + children: ( + <> + Quer gerar textos criativos ou técnicos?{' '} + Experimente o AI21 Labs. + + ) + })} + {li({ + children: ( + <> + + Precisa analisar, classificar ou organizar muitos textos? + {' '} + O Cohere pode ajudar. + + ) + })} + + ) + })} + + {p({ + children: ( + <> + Com esses modelos, você pode escolher a solução que mais combina com + o seu projeto, sem se preocupar com a complexidade técnica. Basta + selecionar o modelo e começar a usar! + + ) + })} + + ) +} + +export default FoundationModelsPage diff --git a/src/features/docs/pages/getting-started.tsx b/src/features/docs/pages/getting-started.tsx new file mode 100644 index 0000000..1dfbbd3 --- /dev/null +++ b/src/features/docs/pages/getting-started.tsx @@ -0,0 +1,360 @@ +import { motion } from 'framer-motion' +import { h1, h2, p, ul, li, pre } from '@/shared/components/typography' + +export function GettingStartedPage() { + return ( + + {h1({ children: 'Comece a Usar o Knowly' })} + + {p({ + children: ( + <> + Siga este guia passo a passo para começar a usar a plataforma Knowly + e criar sua primeira base de conhecimento de IA. + + ) + })} + + {h2({ children: 'Passo 1: Criar uma Conta' })} + {p({ + children: ( + <>Para começar, você precisa criar uma conta gratuita no Knowly: + ) + })} + {ul({ + children: ( + <> + {li({ + children: ( + <> + Acesse a página de{' '} + + cadastro + + + ) + })} + {li({ + children: <>Preencha seus dados: nome, e-mail e senha + })} + {li({ + children: <>Confirme seu e-mail através do link enviado + })} + {li({ + children: ( + <> + Faça login com suas credenciais + + ) + })} + + ) + })} + + {h2({ children: 'Passo 2: Criar uma Base de Conhecimento' })} + {p({ + children: ( + <> + Após fazer login, você pode criar sua primeira base de conhecimento: + + ) + })} + {ul({ + children: ( + <> + {li({ + children: ( + <> + Acesse "Minhas Bases" no menu do + usuário + + ) + })} + {li({ + children: ( + <> + Clique em "Nova Base" + + ) + })} + {li({ + children: ( + <> + Escolha um nome para sua base + + ) + })} + {li({ + children: ( + <> + Selecione o modelo de IA que deseja usar (ex: + Amazon Bedrock) + + ) + })} + {li({ + children: ( + <> + Faça upload dos documentos PDF que servirão + como base de conhecimento + + ) + })} + {li({ + children: ( + <> + Clique em "Criar Base" + + ) + })} + + ) + })} + + {p({ + children: ( + <> + Aguarde alguns instantes enquanto o sistema processa seus + documentos. O tempo varia conforme a quantidade e tamanho dos + arquivos. + + ) + })} + + {h2({ children: 'Passo 3: Obter a Chave da Base' })} + {p({ + children: ( + <> + Depois que sua base estiver pronta, você precisa obter a chave de + API para integrá-la: + + ) + })} + {ul({ + children: ( + <> + {li({ + children: <>Na lista de bases, clique na base que você criou + })} + {li({ + children: ( + <> + Na página de detalhes, copie a Chave da Base{' '} + (Base ID) + + ) + })} + {li({ + children: ( + <> + Copie também sua Chave de API (API Key) nas + configurações da conta + + ) + })} + + ) + })} + + {p({ + children: ( + <> + Importante: Guarde essas chaves em um local seguro. + Você precisará delas para fazer requisições à API. + + ) + })} + + {h2({ children: 'Passo 4: Testar no Playground' })} + {p({ + children: ( + <> + Antes de integrar, você pode testar sua base de conhecimento no + Playground: + + ) + })} + {ul({ + children: ( + <> + {li({ + children: ( + <> + Clique em "Testar no Playground" na + página da base + + ) + })} + {li({ + children: ( + <> + Digite perguntas relacionadas aos documentos que você enviou + + ) + })} + {li({ + children: ( + <> + Veja as respostas geradas pela IA com base no conhecimento da + sua base + + ) + })} + + ) + })} + + {h2({ children: 'Passo 5: Integrar com seu Código' })} + {p({ + children: ( + <> + Agora você pode integrar a base de conhecimento ao seu sistema + usando nossa API REST: + + ) + })} + + {pre({ + children: `# Exemplo usando cURL +curl -X POST https://api.knowly.dev.br/chat \\ + -H "Content-Type: application/json" \\ + -d '{ + "kb_key": "knowly_c81a7410-4c69-45e2-b6c6-79205c3a99fd", + "model": "MISTRAL_SMALL", + "prompt": "Qual é o horário de atendimento?" + }'` + })} + + {p({ + children: ( + <> + Exemplo em JavaScript/Node.js: + + ) + })} + + {pre({ + children: `fetch('https://api.knowly.dev.br/chat', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + kb_key: 'knowly_c81a7410-4c69-45e2-b6c6-79205c3a99fd', + model: 'MISTRAL_SMALL', + prompt: 'Qual é o horário de atendimento?' + }) +}) + .then(response => response.json()) + .then(data => console.log(data.response));` + })} + + {p({ + children: ( + <> + Exemplo em Python: + + ) + })} + + {pre({ + children: `import requests + +response = requests.post( + 'https://api.knowly.dev.br/chat', + headers={ + 'Content-Type': 'application/json', + }, + json={ + 'kb_key': 'knowly_c81a7410-4c69-45e2-b6c6-79205c3a99fd', + 'model': 'MISTRAL_SMALL', + 'prompt': 'Qual é o horário de atendimento?' + } +) + +data = response.json() +print(data['response'])` + })} + + {h2({ children: 'Próximos Passos' })} + {p({ + children: ( + <> + Agora que você já sabe como começar, explore mais recursos da + plataforma: + + ) + })} + {ul({ + children: ( + <> + {li({ + children: ( + <> + Aprenda mais sobre{' '} + + Modelos de Fundação + + + ) + })} + {li({ + children: ( + <> + Veja detalhes sobre{' '} + + + Gerenciamento de Bases de Conhecimento + + + + ) + })} + {li({ + children: ( + <> + Explore opções avançadas de{' '} + + Integração + + + ) + })} + {li({ + children: ( + <> + Gerencie sua{' '} + + Assinatura + + + ) + })} + + ) + })} + + {p({ + children: ( + <> + Precisa de ajuda? Consulte nossa{' '} + + página de FAQ + {' '} + ou entre em{' '} + + contato + + . + + ) + })} + + ) +} + +export default GettingStartedPage diff --git a/src/features/docs/pages/integration-api.tsx b/src/features/docs/pages/integration-api.tsx new file mode 100644 index 0000000..52f5d09 --- /dev/null +++ b/src/features/docs/pages/integration-api.tsx @@ -0,0 +1,84 @@ +import { motion } from 'framer-motion' +import { h1, h2, p, ul, li, pre } from '@/shared/components/typography' + +export function IntegrationApiPage() { + return ( + + {h1({ children: 'Integração via API' })} + + {h2({ children: 'Integração simples via API' })} + {p({ + children: ( + <> + Depois de criar sua base de conhecimento no Knowly, você pode + integrá-la facilmente ao seu sistema usando nossa API. O + funcionamento é parecido com a API da OpenAI, muito usada em + chatbots de atendimento, como no WhatsApp. + + ) + })} + + {h2({ children: 'Como funciona?' })} + {ul({ + children: ( + <> + {li({ + children: ( + <> + Você envia um prompt (mensagem ou pergunta) + para a API, junto com sua chave de acesso. + + ) + })} + {li({ + children: ( + <> + A API responde com a melhor resposta baseada nos documentos + que você enviou para sua base. + + ) + })} + {li({ + children: ( + <> + É possível usar essa integração em sites, sistemas internos, + chatbots e muito mais. + + ) + })} + + ) + })} + + {h2({ children: 'Exemplo de requisição' })} + {pre({ + children: `POST https://api.knowly.dev.br/chat +Headers: + Content-Type: application/json +Body: +{ + "kb_key": "knowly_c81a7410-4c69-45e2-b6c6-79205c3a99fd", + "model": "MISTRAL_SMALL", + "prompt": "Como faço para atualizar meus dados cadastrais?" +}` + })} + + {p({ + children: ( + <> + A resposta virá em formato JSON, com o texto gerado pela IA usando o + conhecimento da sua base. Assim, você pode automatizar atendimentos, + responder dúvidas de clientes ou integrar a IA ao seu sistema de + forma simples e eficiente. + + ) + })} + + ) +} + +export default IntegrationApiPage diff --git a/src/features/docs/pages/integration-instagram.tsx b/src/features/docs/pages/integration-instagram.tsx new file mode 100644 index 0000000..234c1ab --- /dev/null +++ b/src/features/docs/pages/integration-instagram.tsx @@ -0,0 +1,426 @@ +import { motion } from 'framer-motion' +import { h1, h2, p, ul, li, pre } from '@/shared/components/typography' + +export function IntegrationInstagramPage() { + return ( + + {h1({ children: 'Integração com Instagram' })} + + {p({ + children: ( + <> + Automatize respostas nas mensagens diretas (DMs) do Instagram usando + a API do Knowly para responder automaticamente perguntas dos + usuários com base na sua base de conhecimento. + + ) + })} + + {h2({ children: 'Passo 1: Configurar Instagram Business Account' })} + {p({ + children: ( + <> + Para usar a API do Instagram, você precisa ter uma{' '} + Conta Business do Instagram conectada a uma{' '} + Página do Facebook: + + ) + })} + {ul({ + children: ( + <> + {li({ + children: ( + <> + Acesse{' '} + + Meta Business Suite + + + ) + })} + {li({ + children: ( + <>Conecte sua conta do Instagram a uma Página do Facebook + ) + })} + {li({ + children: ( + <> + Converta para uma Conta Business no Instagram + + ) + })} + {li({ + children: ( + <> + Configure as permissões necessárias:{' '} + instagram_basic,{' '} + instagram_manage_messages + + ) + })} + + ) + })} + + {h2({ children: 'Passo 2: Obter Token de Acesso' })} + {p({ + children: ( + <> + No{' '} + + Meta for Developers + + , crie um app e obtenha um token de acesso com as permissões + necessárias para gerenciar mensagens do Instagram. + + ) + })} + + {h2({ children: 'Passo 3: Configurar Webhook' })} + {p({ + children: ( + <> + Configure um webhook para receber notificações de mensagens diretas: + + ) + })} + + {pre({ + children: `# URL do Webhook +https://seu-servidor.com/webhook/instagram + +# Assine o evento: messages +# Receberá notificações quando usuários enviarem DMs + +# Exemplo de payload recebido: +{ + "object": "instagram", + "entry": [{ + "id": "INSTAGRAM_BUSINESS_ACCOUNT_ID", + "time": 1704116400, + "messaging": [{ + "sender": { "id": "USER_ID" }, + "recipient": { "id": "PAGE_ID" }, + "timestamp": 1704116400, + "message": { + "mid": "MESSAGE_ID", + "text": "Qual é o horário de funcionamento?" + } + }] + }] +}` + })} + + {h2({ children: 'Passo 4: Integrar com Knowly API' })} + {p({ + children: ( + <> + Quando receber uma mensagem via webhook, consulte a API do Knowly e + envie a resposta de volta ao usuário: + + ) + })} + + {p({ + children: ( + <> + Exemplo em Node.js: + + ) + })} + + {pre({ + children: `const express = require('express'); +const app = express(); + +app.post('/webhook/instagram', async (req, res) => { + const { entry } = req.body; + + // Processar cada mensagem recebida + for (const event of entry) { + for (const messaging of event.messaging) { + const senderId = messaging.sender.id; + const messageText = messaging.message?.text; + + if (!messageText) continue; + + // Consultar API do Knowly + const knowlyResponse = await fetch('https://api.knowly.dev.br/chat', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + kb_key: 'knowly_c81a7410-4c69-45e2-b6c6-79205c3a99fd', + model: 'MISTRAL_SMALL', + prompt: messageText + }) + }); + + const data = await knowlyResponse.json(); + const aiResponse = data.response; + + // Enviar resposta via Instagram Messaging API + await sendInstagramMessage(senderId, aiResponse); + } + } + + res.sendStatus(200); +}); + +// Função para enviar mensagem pelo Instagram +async function sendInstagramMessage(recipientId, message) { + const pageId = 'SEU_INSTAGRAM_BUSINESS_ACCOUNT_ID'; + + await fetch(\`https://graph.facebook.com/v18.0/\${pageId}/messages\`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Authorization': 'Bearer SEU_TOKEN_INSTAGRAM' + }, + body: JSON.stringify({ + recipient: { id: recipientId }, + message: { text: message } + }) + }); +} + +// Endpoint de verificação do webhook (obrigatório) +app.get('/webhook/instagram', (req, res) => { + const mode = req.query['hub.mode']; + const token = req.query['hub.verify_token']; + const challenge = req.query['hub.challenge']; + + if (mode === 'subscribe' && token === 'SEU_TOKEN_DE_VERIFICACAO') { + res.status(200).send(challenge); + } else { + res.sendStatus(403); + } +});` + })} + + {p({ + children: ( + <> + Exemplo em Python: + + ) + })} + + {pre({ + children: `from flask import Flask, request +import requests + +app = Flask(__name__) + +@app.route('/webhook/instagram', methods=['POST']) +def instagram_webhook(): + data = request.json + + # Processar mensagens + for entry in data.get('entry', []): + for messaging in entry.get('messaging', []): + sender_id = messaging['sender']['id'] + message_text = messaging.get('message', {}).get('text') + + if not message_text: + continue + + # Consultar API do Knowly + knowly_response = requests.post( + 'https://api.knowly.dev.br/chat', + headers={ + 'Content-Type': 'application/json', + }, + json={ + 'kb_key': 'knowly_c81a7410-4c69-45e2-b6c6-79205c3a99fd', + 'model': 'MISTRAL_SMALL', + 'prompt': message_text + } + ) + + ai_response = knowly_response.json()['response'] + + # Enviar resposta pelo Instagram + send_instagram_message(sender_id, ai_response) + + return '', 200 + +def send_instagram_message(recipient_id, message): + page_id = 'SEU_INSTAGRAM_BUSINESS_ACCOUNT_ID' + + requests.post( + f'https://graph.facebook.com/v18.0/{page_id}/messages', + headers={ + 'Content-Type': 'application/json', + 'Authorization': 'Bearer SEU_TOKEN_INSTAGRAM' + }, + json={ + 'recipient': {'id': recipient_id}, + 'message': {'text': message} + } + ) + +@app.route('/webhook/instagram', methods=['GET']) +def verify_webhook(): + mode = request.args.get('hub.mode') + token = request.args.get('hub.verify_token') + challenge = request.args.get('hub.challenge') + + if mode == 'subscribe' and token == 'SEU_TOKEN_DE_VERIFICACAO': + return challenge, 200 + return '', 403` + })} + + {h2({ children: 'Passo 5: Testar a Integração' })} + {ul({ + children: ( + <> + {li({ + children: ( + <> + Envie uma mensagem direta para sua conta Business do Instagram + + ) + })} + {li({ + children: <>Verifique se o webhook está recebendo a notificação + })} + {li({ + children: ( + <> + Confirme que a API do Knowly está retornando respostas + adequadas + + ) + })} + {li({ + children: ( + <> + Valide se as respostas estão sendo enviadas corretamente ao + usuário + + ) + })} + + ) + })} + + {h2({ children: 'Funcionalidades Avançadas' })} + {ul({ + children: ( + <> + {li({ + children: ( + <> + Respostas rápidas: Configure botões de + resposta rápida para melhorar a experiência + + ) + })} + {li({ + children: ( + <> + Mídia: Envie imagens ou vídeos junto com as + respostas quando apropriado + + ) + })} + {li({ + children: ( + <> + Templates: Use templates pré-aprovados para + respostas frequentes + + ) + })} + {li({ + children: ( + <> + Horário comercial: Configure respostas + automáticas apenas fora do horário comercial + + ) + })} + + ) + })} + + {h2({ children: 'Boas Práticas' })} + {ul({ + children: ( + <> + {li({ + children: ( + <> + Transparência: Informe aos usuários que estão + interagindo com um assistente automático + + ) + })} + {li({ + children: ( + <> + Escalação: Ofereça opção de falar com + atendente humano quando necessário + + ) + })} + {li({ + children: ( + <> + Tempo de resposta: Configure timeout adequado + (máx. 10 segundos) + + ) + })} + {li({ + children: ( + <> + Monitoramento: Acompanhe métricas de + satisfação e qualidade das respostas + + ) + })} + {li({ + children: ( + <> + Políticas do Instagram: Respeite as + diretrizes de mensagens automatizadas da plataforma + + ) + })} + + ) + })} + + {p({ + children: ( + <> + Com essa integração, você poderá responder automaticamente mensagens + diretas no Instagram, melhorando o engajamento com sua audiência e + fornecendo suporte instantâneo 24/7. + + ) + })} + + ) +} + +export default IntegrationInstagramPage diff --git a/src/features/docs/pages/integration-whatsapp.tsx b/src/features/docs/pages/integration-whatsapp.tsx new file mode 100644 index 0000000..7e43943 --- /dev/null +++ b/src/features/docs/pages/integration-whatsapp.tsx @@ -0,0 +1,296 @@ +import { motion } from 'framer-motion' +import { h1, h2, p, ul, li, pre } from '@/shared/components/typography' + +export function IntegrationWhatsAppPage() { + return ( + + {h1({ children: 'Integração com WhatsApp Business' })} + + {p({ + children: ( + <> + Automatize o atendimento no WhatsApp Business usando a API do Knowly + para responder automaticamente mensagens de clientes com base na sua + base de conhecimento. + + ) + })} + + {h2({ children: 'Passo 1: Configurar o WhatsApp Business API' })} + {p({ + children: ( + <> + Primeiro, você precisa ter acesso à{' '} + WhatsApp Business API. Você pode configurar através + de: + + ) + })} + {ul({ + children: ( + <> + {li({ + children: ( + <> + Meta Business Platform - Acesse{' '} + + business.facebook.com + {' '} + e configure sua conta + + ) + })} + {li({ + children: ( + <> + Provedores terceiros - Como Twilio, + 360Dialog, ou MessageBird + + ) + })} + + ) + })} + + {h2({ children: 'Passo 2: Configurar Webhook' })} + {p({ + children: ( + <> + Configure um webhook para receber mensagens dos clientes. Este + endpoint receberá as mensagens enviadas ao seu número do WhatsApp + Business. + + ) + })} + + {p({ + children: ( + <> + Exemplo de configuração de webhook: + + ) + })} + + {pre({ + children: `# URL do Webhook +https://seu-servidor.com/webhook/whatsapp + +# Método: POST +# Receberá mensagens no formato: +{ + "from": "5511999999999", + "message": "Qual é o horário de atendimento?", + "timestamp": "2025-01-15T10:30:00Z" +}` + })} + + {h2({ children: 'Passo 3: Integrar com Knowly API' })} + {p({ + children: ( + <> + No seu servidor, ao receber uma mensagem via webhook, faça uma + requisição para a API do Knowly para obter a resposta: + + ) + })} + + {p({ + children: ( + <> + Exemplo em Node.js: + + ) + })} + + {pre({ + children: `// Servidor Express recebendo webhook do WhatsApp +app.post('/webhook/whatsapp', async (req, res) => { + const { from, message } = req.body; + + // Consultar API do Knowly + const knowlyResponse = await fetch('https://api.knowly.dev.br/chat', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + kb_key: 'knowly_c81a7410-4c69-45e2-b6c6-79205c3a99fd', + model: 'MISTRAL_SMALL', + prompt: message + }) + }); + + const data = await knowlyResponse.json(); + const aiResponse = data.response; + + // Enviar resposta de volta para o WhatsApp + await sendWhatsAppMessage(from, aiResponse); + + res.sendStatus(200); +}); + +// Função para enviar mensagem pelo WhatsApp Business API +async function sendWhatsAppMessage(to, message) { + await fetch('https://graph.facebook.com/v18.0/SEU_PHONE_NUMBER_ID/messages', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Authorization': 'Bearer SEU_TOKEN_WHATSAPP' + }, + body: JSON.stringify({ + messaging_product: 'whatsapp', + to: to, + text: { body: message } + }) + }); +}` + })} + + {p({ + children: ( + <> + Exemplo em Python: + + ) + })} + + {pre({ + children: `from flask import Flask, request +import requests + +app = Flask(__name__) + +@app.route('/webhook/whatsapp', methods=['POST']) +def whatsapp_webhook(): + data = request.json + from_number = data['from'] + message = data['message'] + + # Consultar API do Knowly + knowly_response = requests.post( + 'https://api.knowly.dev.br/chat', + headers={ + 'Content-Type': 'application/json', + }, + json={ + 'kb_key': 'knowly_c81a7410-4c69-45e2-b6c6-79205c3a99fd', + 'model': 'MISTRAL_SMALL', + 'prompt': message + } + ) + + ai_response = knowly_response.json()['response'] + + # Enviar resposta pelo WhatsApp Business API + send_whatsapp_message(from_number, ai_response) + + return '', 200 + +def send_whatsapp_message(to, message): + requests.post( + f'https://graph.facebook.com/v18.0/SEU_PHONE_NUMBER_ID/messages', + headers={ + 'Content-Type': 'application/json', + 'Authorization': 'Bearer SEU_TOKEN_WHATSAPP' + }, + json={ + 'messaging_product': 'whatsapp', + 'to': to, + 'text': {'body': message} + } + )` + })} + + {h2({ children: 'Passo 4: Testar a Integração' })} + {ul({ + children: ( + <> + {li({ + children: ( + <>Envie uma mensagem para seu número do WhatsApp Business + ) + })} + {li({ + children: <>Verifique se o webhook está recebendo a mensagem + })} + {li({ + children: ( + <>Confirme que a API do Knowly está retornando respostas + ) + })} + {li({ + children: ( + <> + Valide se as respostas estão sendo enviadas de volta ao + cliente + + ) + })} + + ) + })} + + {h2({ children: 'Dicas Importantes' })} + {ul({ + children: ( + <> + {li({ + children: ( + <> + Timeout: Configure um tempo limite razoável + para requisições (recomendado: 10-15 segundos) + + ) + })} + {li({ + children: ( + <> + Tratamento de erros: Implemente mensagens de + fallback caso a API não responda + + ) + })} + {li({ + children: ( + <> + Rate limiting: Respeite os limites de taxa do + WhatsApp Business API + + ) + })} + {li({ + children: ( + <> + Contexto: Considere manter histórico de + conversas para melhorar as respostas + + ) + })} + + ) + })} + + {p({ + children: ( + <> + Com essa integração, seu WhatsApp Business responderá + automaticamente aos clientes usando o conhecimento da sua base, + proporcionando atendimento 24/7 e reduzindo a carga de trabalho da + equipe. + + ) + })} + + ) +} + +export default IntegrationWhatsAppPage diff --git a/src/features/docs/pages/integration.tsx b/src/features/docs/pages/integration.tsx new file mode 100644 index 0000000..10a5a86 --- /dev/null +++ b/src/features/docs/pages/integration.tsx @@ -0,0 +1,83 @@ +import { motion } from 'framer-motion' +import { h1, h2, p, ul, li, pre } from '@/shared/components/typography' + +export function IntegrationPage() { + return ( + + {h1({ children: 'Como integrar com sua base de conhecimento' })} + + {h2({ children: 'Integração simples via API' })} + {p({ + children: ( + <> + Depois de criar sua base de conhecimento no Knowly, você pode + integrá-la facilmente ao seu sistema usando nossa API. O + funcionamento é parecido com a API da OpenAI, muito usada em + chatbots de atendimento, como no WhatsApp. + + ) + })} + + {h2({ children: 'Como funciona?' })} + {ul({ + children: ( + <> + {li({ + children: ( + <> + Você envia um prompt (mensagem ou pergunta) + para a API, junto com sua chave de acesso. + + ) + })} + {li({ + children: ( + <> + A API responde com a melhor resposta baseada nos documentos + que você enviou para sua base. + + ) + })} + {li({ + children: ( + <> + É possível usar essa integração em sites, sistemas internos, + chatbots e muito mais. + + ) + })} + + ) + })} + + {h2({ children: 'Exemplo de requisição' })} + {pre({ + children: `POST https://api.knowly.ai/v1/query +Headers: + Authorization: Bearer SUA_CHAVE_DE_API +Body: +{ + "prompt": "Como faço para atualizar meus dados cadastrais?", + "baseId": "sua-base-id" +}` + })} + + {p({ + children: ( + <> + A resposta virá em formato JSON, com o texto gerado pela IA usando o + conhecimento da sua base. Assim, você pode automatizar atendimentos, + responder dúvidas de clientes ou integrar a IA ao seu sistema de + forma simples e eficiente. + + ) + })} + + ) +} + +export default IntegrationPage diff --git a/src/features/docs/pages/knowledge-bases.tsx b/src/features/docs/pages/knowledge-bases.tsx new file mode 100644 index 0000000..78192e0 --- /dev/null +++ b/src/features/docs/pages/knowledge-bases.tsx @@ -0,0 +1,63 @@ +import { motion } from 'framer-motion' +import { h1, h2, p, ul, li } from '@/shared/components/typography' + +export function KnowledgeBasesPage() { + return ( + + {h1({ children: 'Gerenciando Bases de Conhecimento' })} + + {h2({ children: 'Como criar, editar e excluir suas bases' })} + {p({ + children: ( + <> + Gerenciar suas bases de conhecimento no Knowly é simples e rápido. + Basta acessar as configurações do seu perfil após fazer login e + selecionar a opção "Minhas bases". + + ) + })} + + {ul({ + children: ( + <> + {li({ + children: ( + <> + Para criar uma base: Clique em{' '} + "Nova base", escolha um nome e + envie os documentos que deseja usar. Pronto! Sua base estará + disponível para consultas e integrações assim que terminar de + ser criada. + + ) + })} + {li({ + children: ( + <> + Para editar: Selecione uma base existente na + lista para ver detalhes, adicionar ou remover documentos, ou + atualizar informações. + + ) + })} + {li({ + children: ( + <> + Para excluir: Escolha a base desejada e + clique em "Excluir". Confirme a + ação para remover a base do sistema. + + ) + })} + + ) + })} + + ) +} + +export default KnowledgeBasesPage diff --git a/src/features/docs/pages/next-steps.tsx b/src/features/docs/pages/next-steps.tsx new file mode 100644 index 0000000..94120c8 --- /dev/null +++ b/src/features/docs/pages/next-steps.tsx @@ -0,0 +1,324 @@ +import { motion } from 'framer-motion' +import { h1, h2, p, ul, li } from '@/shared/components/typography' + +export function NextStepsPage() { + return ( + + {h1({ children: 'Próximos Passos' })} + + {p({ + children: ( + <> + Estamos constantemente inovando e desenvolvendo novas + funcionalidades para tornar o Knowly ainda mais poderoso e fácil de + usar. Confira o que estamos planejando para o futuro da plataforma. + + ) + })} + + {h2({ children: 'Roadmap de Novas Features' })} + + {h2({ children: 'Sistema de Chatbot Multi-Tenant (Em Desenvolvimento)' })} + {p({ + children: ( + <> + Nossa próxima grande funcionalidade é um{' '} + sistema de chatbot multi-tenant completo que + simplificará drasticamente a integração do Knowly em suas + plataformas. + + ) + })} + + {p({ + children: ( + <> + O que é? + + ) + })} + {p({ + children: ( + <> + Um sistema de chatbot gerenciado e hospedado pela Knowly que você + poderá integrar diretamente em seus canais de atendimento, sem + precisar se preocupar com infraestrutura, webhooks ou gerenciamento + de APIs. + + ) + })} + + {p({ + children: ( + <> + Benefícios: + + ) + })} + {ul({ + children: ( + <> + {li({ + children: ( + <> + Zero configuração de infraestrutura: Não será + mais necessário criar e manter servidores para consumir as + APIs das bases de conhecimento + + ) + })} + {li({ + children: ( + <> + Integração simplificada: Basta conectar suas + contas do WhatsApp Business, Instagram, ou outras plataformas + diretamente no painel do Knowly + + ) + })} + {li({ + children: ( + <> + Gerenciamento centralizado: Controle todos os + seus chatbots de diferentes plataformas em um único lugar + + ) + })} + {li({ + children: ( + <> + Multi-tenant: Suporte a múltiplas empresas e + organizações com isolamento completo de dados + + ) + })} + {li({ + children: ( + <> + Escalabilidade automática: Nossa + infraestrutura cuida de todo o dimensionamento automaticamente + + ) + })} + {li({ + children: ( + <> + Monitoramento em tempo real: Acompanhe + métricas de conversas, satisfação e performance dos chatbots + + ) + })} + + ) + })} + + {p({ + children: ( + <> + Plataformas suportadas: + + ) + })} + {ul({ + children: ( + <> + {li({ children: 'WhatsApp Business' })} + {li({ children: 'Instagram Direct Messages' })} + {li({ children: 'Website (Widget de chat embarcado)' })} + {li({ children: 'Facebook Messenger (Em breve)' })} + {li({ children: 'Telegram (Em breve)' })} + {li({ children: 'Slack (Em breve)' })} + {li({ + children: + 'E-commerce (integração com Shopify, WooCommerce, etc.) (Em breve)' + })} + + ) + })} + + {p({ + children: ( + <> + Como funcionará: + + ) + })} + {ul({ + children: ( + <> + {li({ + children: ( + <> + Passo 1: No painel do Knowly, acesse a seção + "Chatbots" + + ) + })} + {li({ + children: ( + <> + Passo 2: Selecione a plataforma que deseja + integrar (WhatsApp, Instagram, Website, etc.) + + ) + })} + {li({ + children: ( + <> + Passo 3: Conecte sua conta seguindo o fluxo + de autenticação simplificado + + ) + })} + {li({ + children: ( + <> + Passo 4: Associe uma ou mais bases de + conhecimento ao chatbot + + ) + })} + {li({ + children: ( + <> + Passo 5: Configure opções como horário de + atendimento, mensagens de boas-vindas, e regras de escalação + + ) + })} + {li({ + children: ( + <> + Passo 6: Ative o chatbot e comece a receber + atendimentos automatizados! + + ) + })} + + ) + })} + + {h2({ children: 'Análises e Insights Avançados' })} + {p({ + children: ( + <> + Além do chatbot multi-tenant, estamos desenvolvendo um sistema + completo de análises para você entender melhor como seus clientes + interagem com a IA: + + ) + })} + {ul({ + children: ( + <> + {li({ + children: + 'Dashboard com métricas de performance das bases de conhecimento' + })} + {li({ + children: 'Análise de sentimento das conversas' + })} + {li({ + children: 'Identificação de perguntas frequentes não respondidas' + })} + {li({ + children: + 'Sugestões de melhoria para otimizar suas bases de conhecimento' + })} + {li({ + children: 'Relatórios de satisfação do cliente' + })} + + ) + })} + + {h2({ children: 'Customização Avançada de Respostas' })} + {ul({ + children: ( + <> + {li({ + children: + 'Templates personalizáveis para diferentes tipos de perguntas' + })} + {li({ + children: + 'Tom de voz configurável (formal, casual, técnico, etc.)' + })} + {li({ + children: + 'Regras de negócio customizadas para tratamento especial de certos tópicos' + })} + {li({ + children: 'Respostas com rich media (imagens, vídeos, carrosséis)' + })} + + ) + })} + + {h2({ children: 'Suporte Multilíngue' })} + {ul({ + children: ( + <> + {li({ + children: 'Detecção automática do idioma do usuário' + })} + {li({ + children: + 'Respostas em múltiplos idiomas a partir da mesma base de conhecimento' + })} + {li({ + children: 'Tradução automática de documentos' + })} + + ) + })} + + {h2({ children: 'Integrações com CRMs e Ferramentas' })} + {ul({ + children: ( + <> + {li({ + children: 'Integração nativa com Salesforce, HubSpot, Pipedrive' + })} + {li({ + children: + 'Webhooks personalizados para integração com qualquer sistema' + })} + {li({ + children: 'API de eventos para rastreamento de conversas' + })} + + ) + })} + + {h2({ children: 'Fique por Dentro' })} + {p({ + children: ( + <> + Estamos trabalhando arduamente para trazer essas funcionalidades o + mais rápido possível. O sistema de chatbot multi-tenant está em fase + avançada de desenvolvimento e será lançado em breve! + + ) + })} + + {p({ + children: ( + <> + Quer ser notificado quando essas features forem lançadas? Entre em{' '} + + contato conosco + {' '} + ou acompanhe nossas atualizações. + + ) + })} + + ) +} + +export default NextStepsPage diff --git a/src/features/docs/pages/playground-testing.tsx b/src/features/docs/pages/playground-testing.tsx new file mode 100644 index 0000000..1e7a64e --- /dev/null +++ b/src/features/docs/pages/playground-testing.tsx @@ -0,0 +1,68 @@ +import { motion } from 'framer-motion' +import { h1, h2, p, ul, li } from '@/shared/components/typography' + +export function PlaygroundTestingPage() { + return ( + + {h1({ children: 'Testando sua Base de Conhecimento no Playground' })} + + {h2({ children: 'O que é o Playground?' })} + {p({ + children: ( + <> + O Playground é uma área do nosso site feita para você testar, na + prática, as bases de conhecimento que criou. Ele funciona como um + chat, parecido com o ChatGPT ou o Gemini, onde você pode conversar + com a sua base e ver as respostas geradas pela inteligência + artificial. + + ) + })} + + {h2({ children: 'Como funciona?' })} + {ul({ + children: ( + <> + {li({ + children: <>Escolha qual base de conhecimento você quer testar. + })} + {li({ + children: ( + <> + Envie perguntas ou comandos (prompts) no chat, como faria em + um atendimento real. + + ) + })} + {li({ + children: ( + <> + Veja as respostas geradas na hora, usando os documentos e + informações que você cadastrou. + + ) + })} + + ) + })} + + {h2({ children: 'Por que usar o Playground?' })} + {p({ + children: ( + <> + O Playground é a maneira mais fácil e rápida de conferir se sua base + está funcionando como esperado. Você pode testar diferentes + perguntas, ajustar seus documentos e experimentar os modelos antes + de integrar a IA ao seu site ou sistema. + + ) + })} + + ) +} + +export default PlaygroundTestingPage diff --git a/src/features/docs/pages/subscription-management.tsx b/src/features/docs/pages/subscription-management.tsx new file mode 100644 index 0000000..a6f0251 --- /dev/null +++ b/src/features/docs/pages/subscription-management.tsx @@ -0,0 +1,66 @@ +import { motion } from 'framer-motion' +import { h1, h2, p, ul, li } from '@/shared/components/typography' + +export function SubscriptionManagementPage() { + return ( + + {h1({ children: 'Gerenciando seu Plano de Assinatura' })} + + {h2({ children: 'Como alterar seu plano' })} + {p({ + children: ( + <> + Para gerenciar seu plano de assinatura no Knowly, é só acessar a + área do usuário após fazer login. No menu lateral à esquerda, clique + em "Assinatura". + + ) + })} + {ul({ + children: ( + <> + {li({ + children: ( + <> + Na seção "Plano atual", procure o + botão "Mudar plano" no canto + inferior direito. + + ) + })} + {li({ + children: ( + <> + Clique em "Mudar plano" para ver as + opções disponíveis e escolher o plano que melhor atende às + suas necessidades. + + ) + })} + {li({ + children: ( + <> + Confirme a alteração e pronto! Seu novo plano já estará ativo. + + ) + })} + + ) + })} + {p({ + children: ( + <> + Assim, você pode ajustar sua assinatura sempre que quiser, de forma + rápida e sem complicação. + + ) + })} + + ) +} + +export default SubscriptionManagementPage diff --git a/src/features/faq/pages/faq-bases-create.tsx b/src/features/faq/pages/faq-bases-create.tsx new file mode 100644 index 0000000..0a14dfc --- /dev/null +++ b/src/features/faq/pages/faq-bases-create.tsx @@ -0,0 +1,158 @@ +import { Background } from '@/shared/components/background' +import { BackgroundBlobs } from '@/shared/components/background-blobs' +import { Layout } from '@/shared/components/layout' +import { Card, CardContent } from '@/shared/components/card' +import { motion } from 'framer-motion' + +export function FAQBasesCreatePage() { + return ( + + + +
+
+ + FAQ + + {'>'} + + Criar nova base + +
+
+ + Como criar uma nova base de conhecimento? + +
+ {/* Seção 1: Passo a passo prático */} + + +

+ Passo a passo para criar sua base de conhecimento +

+
    +
  1. + Faça login na plataforma com seu usuário e senha. + {/* Espaço para imagem de tela de login */} +
    + [Imagem da tela de login] +
    +
  2. +
  3. + Acesse seu perfil e vá até a seção{' '} + Bases de conhecimento. + {/* Espaço para imagem do perfil */} +
    + [Imagem do perfil e menu de bases] +
    +
  4. +
  5. + Clique no botão Criar uma nova base. + {/* Espaço para imagem do botão */} +
    + [Imagem do botão Criar uma nova base] +
    +
  6. +
  7. + Escolha o modelo de base de conhecimento desejado. + {/* Espaço para imagem de seleção de modelo */} +
    + [Imagem da seleção de modelo] +
    +
  8. +
  9. + Faça upload dos documentos que irão compor sua base. + {/* Espaço para imagem de upload */} +
    + [Imagem da tela de upload] +
    +
  10. +
  11. + Aguarde enquanto sua base é criada.
    + + Atenção: esse processo pode demorar alguns minutos, + especialmente se você enviar muitos arquivos. + + {/* Espaço para imagem de carregamento */} +
    + [Imagem de carregamento/criação da base] +
    +
  12. +
  13. + Pronto! Sua base estará disponível para uso via API e para + testes no ambiente sandbox. + {/* Espaço para imagem de base criada */} +
    + [Imagem da base criada e opções de uso] +
    +
  14. +
+
+
+ + {/* Seção 2: Como funciona por trás */} + + +

+ O que acontece por trás do sistema? +

+

+ Após o upload dos arquivos, o sistema salva seus documentos e + inicia o treinamento do modelo de IA escolhido utilizando + exclusivamente os arquivos enviados por você. Nenhum dado + externo é utilizado para treinar sua base, garantindo + privacidade e personalização. +

+ {/* Espaço para esquema ilustrativo */} +
+ [Esquema ilustrativo do fluxo de criação da base] +
+
+
+ + {/* Seção 3: Possíveis erros e soluções */} + + +

+ Possíveis erros e como resolver +

+
    +
  • + Limite de bases atingido: Você já criou o máximo de + bases permitido pelo seu plano. +
    + + Solução: Assine um plano superior ou exclua uma base + existente. + +
  • +
  • + Limite de armazenamento atingido: Você já utilizou todo + o espaço de arquivos do seu plano. +
    + + Solução: Assine um plano superior ou remova arquivos de + outras bases para liberar espaço. + +
  • +
  • + Modelo indisponível: O modelo de base desejado não está + disponível no seu plano. +
    + + Solução: Assine um plano superior para acessar esse modelo. + +
  • +
+
+
+
+
+
+ ) +} diff --git a/src/features/faq/pages/faq-bases-others.tsx b/src/features/faq/pages/faq-bases-others.tsx new file mode 100644 index 0000000..86a3b63 --- /dev/null +++ b/src/features/faq/pages/faq-bases-others.tsx @@ -0,0 +1,76 @@ +import { Background } from '@/shared/components/background' +import { BackgroundBlobs } from '@/shared/components/background-blobs' +import { Layout } from '@/shared/components/layout' +import { Card, CardContent } from '@/shared/components/card' +import { motion } from 'framer-motion' +import { ArrowRightCircle } from 'lucide-react' + +const topics = [ + { + title: 'Como editar uma base de conhecimento', + link: '/faq/bases/edit' + }, + { + title: 'Como excluir uma base de conhecimento', + link: '/faq/bases/delete' + }, + { + title: 'Compartilhamento de bases entre usuários', + link: '/faq/bases/sharing' + }, + { + title: 'Limites de armazenamento e documentos', + link: '/faq/bases/limits' + }, + { + title: 'Erros comuns ao gerenciar bases', + link: '/faq/bases/errors' + } +] + +export function FAQBasesOthersPage() { + return ( + + + +
+
+ + FAQ + + {'>'} + + Bases de conhecimento + +
+
+ + Com qual tema você quer ajuda? + +
+ + + {topics.map((item) => ( + +
+ {item.title} +
+ +
+ ))} +
+
+
+
+
+ ) +} diff --git a/src/features/faq/pages/faq-contact.tsx b/src/features/faq/pages/faq-contact.tsx new file mode 100644 index 0000000..f1db77a --- /dev/null +++ b/src/features/faq/pages/faq-contact.tsx @@ -0,0 +1,173 @@ +import { Background } from '@/shared/components/background' +import { Layout } from '@/shared/components/layout' +import { Card, CardContent } from '@/shared/components/card' +import { Button } from '@/shared/components/button' +import { Input } from '@/shared/components/input' +import { Textarea } from '@/shared/components/textarea' +import { + Form, + FormControl, + FormField, + FormItem, + FormLabel, + FormMessage +} from '@/shared/components/form' +import { useForm } from 'react-hook-form' +import { zodResolver } from '@hookform/resolvers/zod' +import { faqFormSchema, FAQFormData } from '../types/faq-form-schema' +import toast from 'react-hot-toast' + +export function FAQContactPage() { + const form = useForm({ + resolver: zodResolver(faqFormSchema), + mode: 'onBlur' + }) + + const onSubmit = () => { + toast.success('Sua mensagem foi enviada com sucesso!', { + duration: 5000 + }) + form.reset() + } + + return ( + + +
+
+ + FAQ + + {'>'} + Fale conosco +
+
+

+ Fale conosco +

+
+ + +

+ E-mails de contato +

+ + + Se preferir, ou caso não tenha certeza sobre qual e-mail + utilizar, preencha o formulário abaixo + +
+
+ + +

+ Formulário de contato +

+
+ + ( + + Nome + + + + + + )} + /> + ( + + E-mail + + + + + + )} + /> + ( + + Assunto + + + + + + )} + /> + ( + + Mensagem + +