Spaces:
Configuration error
Configuration error
Upload 93 files
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- .eslintrc.json +6 -0
- .gitattributes +2 -35
- .github/workflows/deploy.yml +48 -0
- .gitignore +42 -0
- .npmrc +3 -0
- .vscode/settings.json +7 -0
- CHANGELOG.md +7 -0
- LICENSE +21 -0
- README.md +101 -9
- next.config.js +19 -0
- package.json +60 -0
- pages/_app.tsx +76 -0
- pages/_document.tsx +16 -0
- pages/api/chatAPI.ts +32 -0
- pages/index.tsx +432 -0
- prettier.config.js +4 -0
- public/favicon.ico +0 -0
- public/fonts/dm-sans/DMSans-Bold.ttf +0 -0
- public/fonts/dm-sans/DMSans-BoldItalic.ttf +0 -0
- public/fonts/dm-sans/DMSans-Italic.ttf +0 -0
- public/fonts/dm-sans/DMSans-Medium.ttf +0 -0
- public/fonts/dm-sans/DMSans-MediumItalic.ttf +0 -0
- public/fonts/dm-sans/DMSans-Regular.ttf +0 -0
- public/fonts/dm-sans/OFL.txt +93 -0
- public/img/avatars/avatar1.png +0 -0
- public/img/avatars/avatar10.png +0 -0
- public/img/avatars/avatar2.png +0 -0
- public/img/avatars/avatar3.png +0 -0
- public/img/avatars/avatar4.png +0 -0
- public/img/avatars/avatar5.png +0 -0
- public/img/avatars/avatar6.png +0 -0
- public/img/avatars/avatar7.png +0 -0
- public/img/avatars/avatar8.png +0 -0
- public/img/avatars/avatar9.png +0 -0
- public/img/avatars/avatarSimmmple.png +0 -0
- public/img/chat/bg-image.png +0 -0
- public/img/layout/Navbar.png +0 -0
- public/img/layout/logoWhite.png +0 -0
- public/img/plan/InvoiceBg.png +0 -0
- public/manifest.json +15 -0
- public/robots.txt +3 -0
- src/components/CodeBlock.tsx +52 -0
- src/components/MarkdownBlock.tsx +42 -0
- src/components/MessageBox.tsx +24 -0
- src/components/apiModal/index.tsx +253 -0
- src/components/card/Card.tsx +11 -0
- src/components/fields/InputField.tsx +64 -0
- src/components/footer/FooterAdmin.tsx +102 -0
- src/components/icons/IconBox.tsx +17 -0
- src/components/icons/Icons.tsx +200 -0
.eslintrc.json
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"extends": "next/core-web-vitals",
|
| 3 |
+
"rules": {
|
| 4 |
+
"react/no-unescaped-entities": ["error", { "forbid": [">", "}"] }]
|
| 5 |
+
}
|
| 6 |
+
}
|
.gitattributes
CHANGED
|
@@ -1,35 +1,2 @@
|
|
| 1 |
-
|
| 2 |
-
|
| 3 |
-
*.bin filter=lfs diff=lfs merge=lfs -text
|
| 4 |
-
*.bz2 filter=lfs diff=lfs merge=lfs -text
|
| 5 |
-
*.ckpt filter=lfs diff=lfs merge=lfs -text
|
| 6 |
-
*.ftz filter=lfs diff=lfs merge=lfs -text
|
| 7 |
-
*.gz filter=lfs diff=lfs merge=lfs -text
|
| 8 |
-
*.h5 filter=lfs diff=lfs merge=lfs -text
|
| 9 |
-
*.joblib filter=lfs diff=lfs merge=lfs -text
|
| 10 |
-
*.lfs.* filter=lfs diff=lfs merge=lfs -text
|
| 11 |
-
*.mlmodel filter=lfs diff=lfs merge=lfs -text
|
| 12 |
-
*.model filter=lfs diff=lfs merge=lfs -text
|
| 13 |
-
*.msgpack filter=lfs diff=lfs merge=lfs -text
|
| 14 |
-
*.npy filter=lfs diff=lfs merge=lfs -text
|
| 15 |
-
*.npz filter=lfs diff=lfs merge=lfs -text
|
| 16 |
-
*.onnx filter=lfs diff=lfs merge=lfs -text
|
| 17 |
-
*.ot filter=lfs diff=lfs merge=lfs -text
|
| 18 |
-
*.parquet filter=lfs diff=lfs merge=lfs -text
|
| 19 |
-
*.pb filter=lfs diff=lfs merge=lfs -text
|
| 20 |
-
*.pickle filter=lfs diff=lfs merge=lfs -text
|
| 21 |
-
*.pkl filter=lfs diff=lfs merge=lfs -text
|
| 22 |
-
*.pt filter=lfs diff=lfs merge=lfs -text
|
| 23 |
-
*.pth filter=lfs diff=lfs merge=lfs -text
|
| 24 |
-
*.rar filter=lfs diff=lfs merge=lfs -text
|
| 25 |
-
*.safetensors filter=lfs diff=lfs merge=lfs -text
|
| 26 |
-
saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
| 27 |
-
*.tar.* filter=lfs diff=lfs merge=lfs -text
|
| 28 |
-
*.tar filter=lfs diff=lfs merge=lfs -text
|
| 29 |
-
*.tflite filter=lfs diff=lfs merge=lfs -text
|
| 30 |
-
*.tgz filter=lfs diff=lfs merge=lfs -text
|
| 31 |
-
*.wasm filter=lfs diff=lfs merge=lfs -text
|
| 32 |
-
*.xz filter=lfs diff=lfs merge=lfs -text
|
| 33 |
-
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
-
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
-
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
| 1 |
+
# Auto detect text files and perform LF normalization
|
| 2 |
+
* text=auto
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.github/workflows/deploy.yml
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
|
| 2 |
+
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
|
| 3 |
+
|
| 4 |
+
name: Node.js CI
|
| 5 |
+
|
| 6 |
+
on:
|
| 7 |
+
push:
|
| 8 |
+
branches: [feature/live-preview]
|
| 9 |
+
pull_request:
|
| 10 |
+
branches: [feature/live-preview]
|
| 11 |
+
|
| 12 |
+
jobs:
|
| 13 |
+
build:
|
| 14 |
+
runs-on: ubuntu-latest
|
| 15 |
+
|
| 16 |
+
strategy:
|
| 17 |
+
matrix:
|
| 18 |
+
node-version: [14.x]
|
| 19 |
+
|
| 20 |
+
steps:
|
| 21 |
+
- name: Set Actions Allow Unsecure Commands
|
| 22 |
+
run: |
|
| 23 |
+
echo "ACTIONS_ALLOW_UNSECURE_COMMANDS=true" >> $GITHUB_ENV
|
| 24 |
+
|
| 25 |
+
- uses: actions/checkout@v2
|
| 26 |
+
- name: Use Node.js ${{ matrix.node-version }}
|
| 27 |
+
uses: actions/setup-node@v1
|
| 28 |
+
with:
|
| 29 |
+
node-version: ${{ matrix.node-version }}
|
| 30 |
+
|
| 31 |
+
- name: Installing my packages
|
| 32 |
+
run: yarn install
|
| 33 |
+
|
| 34 |
+
- name: Build my App
|
| 35 |
+
run: yarn build
|
| 36 |
+
env:
|
| 37 |
+
NEXT_PUBLIC_BASE_PATH: /chakra-nextjs-pro
|
| 38 |
+
- run: yarn export
|
| 39 |
+
env:
|
| 40 |
+
NEXT_PUBLIC_BASE_PATH: /chakra-nextjs-pro
|
| 41 |
+
- run: touch ./out/.nojekyll
|
| 42 |
+
|
| 43 |
+
- name: Deploy 🚀
|
| 44 |
+
uses: JamesIves/github-pages-deploy-action@3.5.9
|
| 45 |
+
with:
|
| 46 |
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
| 47 |
+
BRANCH: gh-pages
|
| 48 |
+
FOLDER: out
|
.gitignore
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
| 2 |
+
|
| 3 |
+
# dependencies
|
| 4 |
+
node_modules
|
| 5 |
+
/node_modules
|
| 6 |
+
package-lock.json
|
| 7 |
+
yarn.lock
|
| 8 |
+
/.pnp
|
| 9 |
+
.pnp.js
|
| 10 |
+
|
| 11 |
+
# testing
|
| 12 |
+
/coverage
|
| 13 |
+
|
| 14 |
+
# production
|
| 15 |
+
/build
|
| 16 |
+
build
|
| 17 |
+
|
| 18 |
+
# misc
|
| 19 |
+
.DS_Store
|
| 20 |
+
.env.local
|
| 21 |
+
.env.development.local
|
| 22 |
+
.env.test.local
|
| 23 |
+
.env.production.local
|
| 24 |
+
|
| 25 |
+
npm-debug.log*
|
| 26 |
+
yarn-debug.log*
|
| 27 |
+
yarn-error.log*
|
| 28 |
+
*.pem
|
| 29 |
+
.pnpm-debug.log*
|
| 30 |
+
|
| 31 |
+
# nextjs
|
| 32 |
+
/.next/
|
| 33 |
+
/out/
|
| 34 |
+
|
| 35 |
+
# vercel
|
| 36 |
+
.vercel
|
| 37 |
+
|
| 38 |
+
# typescript
|
| 39 |
+
*.tsbuildinfo
|
| 40 |
+
next-env.d.ts
|
| 41 |
+
|
| 42 |
+
.idea
|
.npmrc
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
legacy-peer-deps=true
|
| 2 |
+
auto-install-peers=true
|
| 3 |
+
strict-peer-dependencies=false
|
.vscode/settings.json
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"prettier.singleQuote": true,
|
| 3 |
+
"prettier.semi": true,
|
| 4 |
+
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
| 5 |
+
"typescript.tsdk": "node_modules/typescript/lib",
|
| 6 |
+
"typescript.enablePromptUseWorkspaceTsdk": true
|
| 7 |
+
}
|
CHANGELOG.md
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Changelog
|
| 2 |
+
|
| 3 |
+
## [1.0.0] 2023-06-20
|
| 4 |
+
|
| 5 |
+
### Official Release
|
| 6 |
+
|
| 7 |
+
Added TypeScript & NextJS
|
LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
MIT License
|
| 2 |
+
|
| 3 |
+
Copyright (c) 2023 Horizon UI
|
| 4 |
+
|
| 5 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
| 6 |
+
of this software and associated documentation files (the "Software"), to deal
|
| 7 |
+
in the Software without restriction, including without limitation the rights
|
| 8 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 9 |
+
copies of the Software, and to permit persons to whom the Software is
|
| 10 |
+
furnished to do so, subject to the following conditions:
|
| 11 |
+
|
| 12 |
+
The above copyright notice and this permission notice shall be included in all
|
| 13 |
+
copies or substantial portions of the Software.
|
| 14 |
+
|
| 15 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
| 16 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
| 17 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
| 18 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
| 19 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
| 20 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
| 21 |
+
SOFTWARE.
|
README.md
CHANGED
|
@@ -1,12 +1,104 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
---
|
| 2 |
-
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 10 |
---
|
| 11 |
|
| 12 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# [Horizon ChatGPT AI Template](https://horizon-ui.com/chatgpt-ai-template) [](https://twitter.com/intent/tweet?text=Check%20Horizon%20ChatGPT%20AI%20Template,%20the%20trendiest%20open%20source%20ChatGPT%20AI%20admin%20template%20for%20%23nextjs%20and%20%23react!%0A%0Ahttps%3A//horizon-ui.com/chatgpt-ai-template/%20%20)
|
| 2 |
+
|
| 3 |
+

|
| 4 |
+
[](https://github.com/horizon-ui/chatgpt-ai-template/issues?q=is%3Aopen+is%3Aissue)
|
| 5 |
+
|
| 6 |
+
<p> </p>
|
| 7 |
+
|
| 8 |
+
[<img alt="Horizon UI - Tailwind CSS React Admin dashboard template" src="https://i.ibb.co/Qmym1qt/horizon-ai-template-presentation-image-open-source.png" />](https://horizon-ui.com/ai-template)
|
| 9 |
+
|
| 10 |
+
<p> </p>
|
| 11 |
+
|
| 12 |
+
Get started and build your dream AI web app with Horizon AI Template, the trendiest & innovative Open-Source Free ChatGPT AI Admin Template for NextJS & React!
|
| 13 |
+
|
| 14 |
---
|
| 15 |
+
|
| 16 |
+
### Introduction
|
| 17 |
+
|
| 18 |
+
Horizon ChatGPT AI Template is the world's best open source OpenAI ChatGPT AI Template made with React, NextJS and Chakra UI! Start creating outstanding Chat AI SaaS Apps faster.
|
| 19 |
+
|
| 20 |
+
It comes with over 30+ dark/light frontend individual elements, like buttons, inputs, navbars, nav tabs, cards, or alerts, giving you the freedom of choosing and combining.
|
| 21 |
+
|
| 22 |
+
### Documentation
|
| 23 |
+
|
| 24 |
+
Each element is well presented in a very complex documentation. You can read more about the <a href="https://horizon-ui.com/docs-ai-template/?ref=readme-horizon-ai-template-free" target="_blank">documentation here.</a>
|
| 25 |
+
|
| 26 |
+
### Quick Start
|
| 27 |
+
|
| 28 |
+
Install Horizon ChatGPT AI Template by running either of the following:
|
| 29 |
+
|
| 30 |
+
- Install NodeJS LTS from [NodeJs Official Page](https://nodejs.org/en/?ref=horizon-documentation) (NOTE: Product only works with LTS version)
|
| 31 |
+
|
| 32 |
+
Clone the repository with the following command:
|
| 33 |
+
|
| 34 |
+
```bash
|
| 35 |
+
git clone https://github.com/horizon-ui/chatgpt-ai-template.git
|
| 36 |
+
```
|
| 37 |
+
|
| 38 |
+
Run in the terminal this command:
|
| 39 |
+
|
| 40 |
+
```bash
|
| 41 |
+
npm install
|
| 42 |
+
```
|
| 43 |
+
|
| 44 |
+
Then run this command to start your local server
|
| 45 |
+
|
| 46 |
+
```bash
|
| 47 |
+
npm run dev
|
| 48 |
+
```
|
| 49 |
+
|
| 50 |
+
### Your API Key is not working?
|
| 51 |
+
|
| 52 |
+
- Make sure you have an [OpenAI account](https://platform.openai.com/account) and a valid API key to use ChatGPT. We don't sell API keys.
|
| 53 |
+
- Make sure you have your billing info added in [OpenAI Billing page](https://platform.openai.com/account/billing/overview). Without billing info, your API key will not work.
|
| 54 |
+
- The app will connect to the OpenAI API server to check if your API Key is working properly.
|
| 55 |
+
|
| 56 |
+
### ATTENTION: The model: `GPT-4` does not work yet.
|
| 57 |
+
If you are trying to use GPT-4, model it will not work if you don't have access from OpenAI.
|
| 58 |
+
Note that even if you have ChatGPT Plus, you still need to request access to the GPT-4 API in order to use it with your API Key.
|
| 59 |
+
This is OpenAI's restriction and we can't do anything about it. You can join the waitlist [here](https://openai.com/waitlist/gpt-4-api) .
|
| 60 |
+
|
| 61 |
+
|
| 62 |
+
### Example Page
|
| 63 |
+
|
| 64 |
+
If you want to get inspiration or just show something directly to your clients, you can jump start your development with our pre-built example page. You will be able to quickly set up the basic structure for your web project.
|
| 65 |
+
|
| 66 |
+
View <a href="https://horizon-ui.com/chatgpt-ai-template/?ref=readme-horizon-ai-template-free" target="_blank">example pages here.</a>
|
| 67 |
+
|
| 68 |
+
### Versions
|
| 69 |
+
|
| 70 |
+
| Free Version | PRO Version |
|
| 71 |
+
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
| 72 |
+
| [](https://github.com/horizon-ui/chatgpt-ai-template) | [](https://www.horizon-ui.com/ai-template?ref=readme-horizon-ai-template-free) |
|
| 73 |
+
|
| 74 |
+
### Figma Version
|
| 75 |
+
|
| 76 |
+
Horizon AI Template is available in Figma format as well! Check Figma
|
| 77 |
+
files in your .zip files! 🎨
|
| 78 |
+
|
| 79 |
+
### Reporting Issues
|
| 80 |
+
|
| 81 |
+
We use GitHub Issues as the official bug tracker for the Horizon UI. Here are
|
| 82 |
+
some advices for our users that want to report an issue:
|
| 83 |
+
|
| 84 |
+
1. Make sure that you are using the latest version of the Horizon AI Template.
|
| 85 |
+
Check the CHANGELOG from your dashboard on our
|
| 86 |
+
[CHANGE LOG File](https://github.com/horizon-ui/chatgpt-ai-template/blob/main/CHANGELOG.md?ref=readme-horizon-ai-template-free).
|
| 87 |
+
2. Providing us reproducible steps for the issue will shorten the time it takes
|
| 88 |
+
for it to be fixed.
|
| 89 |
+
3. Some issues may be browser specific, so specifying in what browser you
|
| 90 |
+
encountered the issue might help.
|
| 91 |
+
|
| 92 |
---
|
| 93 |
|
| 94 |
+
### Community
|
| 95 |
+
|
| 96 |
+
Connect with the community! Feel free to ask questions, report issues, and meet new people that already use Horizon AI Template!
|
| 97 |
+
|
| 98 |
+
💬 [Join the #HorizonUI Discord Community!](https://discord.gg/f6tEKFBd4m)
|
| 99 |
+
|
| 100 |
+
### Copyright and license
|
| 101 |
+
|
| 102 |
+
⭐️ [Copyright 2023 Horizon UI ](https://www.horizon-ui.com/?ref=readme-horizon-ai-template-free)
|
| 103 |
+
|
| 104 |
+
📄 [Horizon UI License](https://horizon-ui.notion.site/End-User-License-Agreement-8fb09441ea8c4c08b60c37996195a6d5)
|
next.config.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/** @type {import('next').NextConfig} */
|
| 2 |
+
|
| 3 |
+
const nextConfig = {
|
| 4 |
+
reactStrictMode: false,
|
| 5 |
+
swcMinify: true,
|
| 6 |
+
basePath: process.env.NEXT_PUBLIC_BASE_PATH,
|
| 7 |
+
assetPrefix: process.env.NEXT_PUBLIC_BASE_PATH,
|
| 8 |
+
images: {
|
| 9 |
+
domains: [
|
| 10 |
+
'images.unsplash.com',
|
| 11 |
+
'i.ibb.co',
|
| 12 |
+
'scontent.fotp8-1.fna.fbcdn.net',
|
| 13 |
+
],
|
| 14 |
+
// Make ENV
|
| 15 |
+
unoptimized: true,
|
| 16 |
+
},
|
| 17 |
+
};
|
| 18 |
+
|
| 19 |
+
module.exports = nextConfig;
|
package.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"name": "horizon-ai-template-pro",
|
| 3 |
+
"version": "1.0.0",
|
| 4 |
+
"private": true,
|
| 5 |
+
"scripts": {
|
| 6 |
+
"dev": "next dev",
|
| 7 |
+
"build": "next build",
|
| 8 |
+
"start": "next start",
|
| 9 |
+
"lint": "next lint"
|
| 10 |
+
},
|
| 11 |
+
"dependencies": {
|
| 12 |
+
"@chakra-ui/icons": "^1.1.5",
|
| 13 |
+
"@chakra-ui/react": "1.8.9",
|
| 14 |
+
"@chakra-ui/system": "^1.12.1",
|
| 15 |
+
"@chakra-ui/theme-tools": "^1.3.6",
|
| 16 |
+
"@codemirror/legacy-modes": "^6.3.2",
|
| 17 |
+
"@emotion/react": "^11.4.1",
|
| 18 |
+
"@emotion/styled": "^11.3.0",
|
| 19 |
+
"@heroicons/react": "^2.0.17",
|
| 20 |
+
"@material-tailwind/react": "^1.4.2",
|
| 21 |
+
"@tanstack/react-table": "^8.5.15",
|
| 22 |
+
"@testing-library/jest-dom": "^5.14.1",
|
| 23 |
+
"@testing-library/react": "^11.2.7",
|
| 24 |
+
"@testing-library/user-event": "^12.8.3",
|
| 25 |
+
"@uiw/codemirror-theme-tokyo-night": "^4.19.11",
|
| 26 |
+
"@uiw/react-codemirror": "^4.19.11",
|
| 27 |
+
"babel-cli": "^6.26.0",
|
| 28 |
+
"babel-preset-es2015": "^6.24.1",
|
| 29 |
+
"babel-preset-react": "^6.24.1",
|
| 30 |
+
"babel-register": "^6.26.0",
|
| 31 |
+
"endent": "^2.1.0",
|
| 32 |
+
"eventsource-parser": "^1.0.0",
|
| 33 |
+
"framer-motion": "^4.1.17",
|
| 34 |
+
"next": "13.2.4",
|
| 35 |
+
"react": "18.2.0",
|
| 36 |
+
"react-build-sitemap": "^0.2.2",
|
| 37 |
+
"react-custom-scrollbars-2": "^4.2.1",
|
| 38 |
+
"react-dom": "18.2.0",
|
| 39 |
+
"react-icons": "^4.9.0",
|
| 40 |
+
"react-is": "^18.0.0",
|
| 41 |
+
"react-markdown": "^8.0.6",
|
| 42 |
+
"react-router-dom": "^5.3.0",
|
| 43 |
+
"react-scripts": "5.0.0",
|
| 44 |
+
"remark-gfm": "^3.0.1",
|
| 45 |
+
"typescript": "4.9.5",
|
| 46 |
+
"web-vitals": "^1.1.2"
|
| 47 |
+
},
|
| 48 |
+
"devDependencies": {
|
| 49 |
+
"@types/node": "18.15.11",
|
| 50 |
+
"@types/react": "18.0.31",
|
| 51 |
+
"@types/react-dom": "18.0.11",
|
| 52 |
+
"autoprefixer": "^10.4.14",
|
| 53 |
+
"eslint": "8.37.0",
|
| 54 |
+
"eslint-config-next": "13.2.4",
|
| 55 |
+
"eventsource": "^2.0.2",
|
| 56 |
+
"postcss": "^8.4.21",
|
| 57 |
+
"prettier-plugin-tailwindcss": "^0.2.6",
|
| 58 |
+
"tailwindcss": "^3.3.1"
|
| 59 |
+
}
|
| 60 |
+
}
|
pages/_app.tsx
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
'use client';
|
| 2 |
+
import type { AppProps } from 'next/app';
|
| 3 |
+
import { ChakraProvider, Box, Portal, useDisclosure } from '@chakra-ui/react';
|
| 4 |
+
import theme from '@/theme/theme';
|
| 5 |
+
import routes from '@/routes';
|
| 6 |
+
import Sidebar from '@/components/sidebar/Sidebar';
|
| 7 |
+
import Footer from '@/components/footer/FooterAdmin';
|
| 8 |
+
import Navbar from '@/components/navbar/NavbarAdmin';
|
| 9 |
+
import { getActiveRoute, getActiveNavbar } from '@/utils/navigation';
|
| 10 |
+
import { usePathname } from 'next/navigation';
|
| 11 |
+
import { useEffect, useState } from 'react';
|
| 12 |
+
import '@/styles/App.css';
|
| 13 |
+
import '@/styles/Contact.css';
|
| 14 |
+
import '@/styles/Plugins.css';
|
| 15 |
+
import '@/styles/MiniCalendar.css';
|
| 16 |
+
|
| 17 |
+
function App({ Component, pageProps }: AppProps<{}>) {
|
| 18 |
+
const pathname = usePathname();
|
| 19 |
+
const [apiKey, setApiKey] = useState('');
|
| 20 |
+
const { isOpen, onOpen, onClose } = useDisclosure();
|
| 21 |
+
useEffect(() => {
|
| 22 |
+
const initialKey = localStorage.getItem('apiKey');
|
| 23 |
+
if (initialKey?.includes('sk-') && apiKey !== initialKey) {
|
| 24 |
+
setApiKey(initialKey);
|
| 25 |
+
}
|
| 26 |
+
}, [apiKey]);
|
| 27 |
+
|
| 28 |
+
return (
|
| 29 |
+
<ChakraProvider theme={theme}>
|
| 30 |
+
<Box>
|
| 31 |
+
<Sidebar setApiKey={setApiKey} routes={routes} />
|
| 32 |
+
<Box
|
| 33 |
+
pt={{ base: '60px', md: '100px' }}
|
| 34 |
+
float="right"
|
| 35 |
+
minHeight="100vh"
|
| 36 |
+
height="100%"
|
| 37 |
+
overflow="auto"
|
| 38 |
+
position="relative"
|
| 39 |
+
maxHeight="100%"
|
| 40 |
+
w={{ base: '100%', xl: 'calc( 100% - 290px )' }}
|
| 41 |
+
maxWidth={{ base: '100%', xl: 'calc( 100% - 290px )' }}
|
| 42 |
+
transition="all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1)"
|
| 43 |
+
transitionDuration=".2s, .2s, .35s"
|
| 44 |
+
transitionProperty="top, bottom, width"
|
| 45 |
+
transitionTimingFunction="linear, linear, ease"
|
| 46 |
+
>
|
| 47 |
+
<Portal>
|
| 48 |
+
<Box>
|
| 49 |
+
<Navbar
|
| 50 |
+
setApiKey={setApiKey}
|
| 51 |
+
onOpen={onOpen}
|
| 52 |
+
logoText={'Horizon UI Dashboard PRO'}
|
| 53 |
+
brandText={getActiveRoute(routes, pathname)}
|
| 54 |
+
secondary={getActiveNavbar(routes, pathname)}
|
| 55 |
+
/>
|
| 56 |
+
</Box>
|
| 57 |
+
</Portal>
|
| 58 |
+
<Box
|
| 59 |
+
mx="auto"
|
| 60 |
+
p={{ base: '20px', md: '30px' }}
|
| 61 |
+
pe="20px"
|
| 62 |
+
minH="100vh"
|
| 63 |
+
pt="50px"
|
| 64 |
+
>
|
| 65 |
+
<Component apiKeyApp={apiKey} {...pageProps} />
|
| 66 |
+
</Box>
|
| 67 |
+
<Box>
|
| 68 |
+
<Footer />
|
| 69 |
+
</Box>
|
| 70 |
+
</Box>
|
| 71 |
+
</Box>
|
| 72 |
+
</ChakraProvider>
|
| 73 |
+
);
|
| 74 |
+
}
|
| 75 |
+
|
| 76 |
+
export default App;
|
pages/_document.tsx
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { Html, Head, Main, NextScript } from 'next/document';
|
| 2 |
+
import Script from 'next/script';
|
| 3 |
+
|
| 4 |
+
export default function Document() {
|
| 5 |
+
return (
|
| 6 |
+
<Html lang="en">
|
| 7 |
+
<Head>
|
| 8 |
+
<title>Horizon AI Template Free</title>
|
| 9 |
+
</Head>
|
| 10 |
+
<body suppressHydrationWarning={true}>
|
| 11 |
+
<Main />
|
| 12 |
+
<NextScript />
|
| 13 |
+
</body>
|
| 14 |
+
</Html>
|
| 15 |
+
);
|
| 16 |
+
}
|
pages/api/chatAPI.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { ChatBody } from '@/types/types';
|
| 2 |
+
import { OpenAIStream } from '@/utils/chatStream';
|
| 3 |
+
|
| 4 |
+
export const config = {
|
| 5 |
+
runtime: 'edge',
|
| 6 |
+
};
|
| 7 |
+
|
| 8 |
+
const handler = async (req: Request): Promise<Response> => {
|
| 9 |
+
try {
|
| 10 |
+
const { inputCode, model, apiKey } = (await req.json()) as ChatBody;
|
| 11 |
+
let apiKeyFinal;
|
| 12 |
+
|
| 13 |
+
if (apiKey) {
|
| 14 |
+
apiKeyFinal = apiKey;
|
| 15 |
+
} else {
|
| 16 |
+
apiKeyFinal = process.env.NEXT_PUBLIC_OPENAI_API_KEY;
|
| 17 |
+
}
|
| 18 |
+
|
| 19 |
+
if (!apiKey) {
|
| 20 |
+
return new Response('API key not found', { status: 500 });
|
| 21 |
+
}
|
| 22 |
+
|
| 23 |
+
const stream = await OpenAIStream(inputCode, model, apiKeyFinal);
|
| 24 |
+
|
| 25 |
+
return new Response(stream);
|
| 26 |
+
} catch (error) {
|
| 27 |
+
console.error(error);
|
| 28 |
+
return new Response('Error', { status: 500 });
|
| 29 |
+
}
|
| 30 |
+
};
|
| 31 |
+
|
| 32 |
+
export default handler;
|
pages/index.tsx
ADDED
|
@@ -0,0 +1,432 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
'use client';
|
| 2 |
+
/*eslint-disable*/
|
| 3 |
+
|
| 4 |
+
import Link from '@/components/link/Link';
|
| 5 |
+
import MessageBoxChat from '@/components/MessageBox';
|
| 6 |
+
import { ChatBody, OpenAIModel } from '@/types/types';
|
| 7 |
+
import {
|
| 8 |
+
Accordion,
|
| 9 |
+
AccordionButton,
|
| 10 |
+
AccordionIcon,
|
| 11 |
+
AccordionItem,
|
| 12 |
+
AccordionPanel,
|
| 13 |
+
Box,
|
| 14 |
+
Button,
|
| 15 |
+
Flex,
|
| 16 |
+
Icon,
|
| 17 |
+
Image,
|
| 18 |
+
Img,
|
| 19 |
+
Input,
|
| 20 |
+
Text,
|
| 21 |
+
useColorModeValue,
|
| 22 |
+
} from '@chakra-ui/react';
|
| 23 |
+
import { useEffect, useState } from 'react';
|
| 24 |
+
import { MdAutoAwesome, MdBolt, MdEdit, MdPerson } from 'react-icons/md';
|
| 25 |
+
import Bg from '../public/img/chat/bg-image.png';
|
| 26 |
+
|
| 27 |
+
export default function Chat(props: { apiKeyApp: string }) {
|
| 28 |
+
// *** If you use .env.local variable for your API key, method which we recommend, use the apiKey variable commented below
|
| 29 |
+
const { apiKeyApp } = props;
|
| 30 |
+
// Input States
|
| 31 |
+
const [inputOnSubmit, setInputOnSubmit] = useState<string>('');
|
| 32 |
+
const [inputCode, setInputCode] = useState<string>('');
|
| 33 |
+
// Response message
|
| 34 |
+
const [outputCode, setOutputCode] = useState<string>('');
|
| 35 |
+
// ChatGPT model
|
| 36 |
+
const [model, setModel] = useState<OpenAIModel>('gpt-3.5-turbo');
|
| 37 |
+
// Loading state
|
| 38 |
+
const [loading, setLoading] = useState<boolean>(false);
|
| 39 |
+
|
| 40 |
+
// API Key
|
| 41 |
+
// const [apiKey, setApiKey] = useState<string>(apiKeyApp);
|
| 42 |
+
const borderColor = useColorModeValue('gray.200', 'whiteAlpha.200');
|
| 43 |
+
const inputColor = useColorModeValue('navy.700', 'white');
|
| 44 |
+
const iconColor = useColorModeValue('brand.500', 'white');
|
| 45 |
+
const bgIcon = useColorModeValue(
|
| 46 |
+
'linear-gradient(180deg, #FBFBFF 0%, #CACAFF 100%)',
|
| 47 |
+
'whiteAlpha.200',
|
| 48 |
+
);
|
| 49 |
+
const brandColor = useColorModeValue('brand.500', 'white');
|
| 50 |
+
const buttonBg = useColorModeValue('white', 'whiteAlpha.100');
|
| 51 |
+
const gray = useColorModeValue('gray.500', 'white');
|
| 52 |
+
const buttonShadow = useColorModeValue(
|
| 53 |
+
'14px 27px 45px rgba(112, 144, 176, 0.2)',
|
| 54 |
+
'none',
|
| 55 |
+
);
|
| 56 |
+
const textColor = useColorModeValue('navy.700', 'white');
|
| 57 |
+
const placeholderColor = useColorModeValue(
|
| 58 |
+
{ color: 'gray.500' },
|
| 59 |
+
{ color: 'whiteAlpha.600' },
|
| 60 |
+
);
|
| 61 |
+
const handleTranslate = async () => {
|
| 62 |
+
const apiKey = apiKeyApp;
|
| 63 |
+
setInputOnSubmit(inputCode);
|
| 64 |
+
|
| 65 |
+
// Chat post conditions(maximum number of characters, valid message etc.)
|
| 66 |
+
const maxCodeLength = model === 'gpt-3.5-turbo' ? 700 : 700;
|
| 67 |
+
|
| 68 |
+
if (!apiKeyApp?.includes('sk-') && !apiKey?.includes('sk-')) {
|
| 69 |
+
alert('Please enter an API key.');
|
| 70 |
+
return;
|
| 71 |
+
}
|
| 72 |
+
|
| 73 |
+
if (!inputCode) {
|
| 74 |
+
alert('Please enter your message.');
|
| 75 |
+
return;
|
| 76 |
+
}
|
| 77 |
+
|
| 78 |
+
if (inputCode.length > maxCodeLength) {
|
| 79 |
+
alert(
|
| 80 |
+
`Please enter code less than ${maxCodeLength} characters. You are currently at ${inputCode.length} characters.`,
|
| 81 |
+
);
|
| 82 |
+
return;
|
| 83 |
+
}
|
| 84 |
+
setOutputCode(' ');
|
| 85 |
+
setLoading(true);
|
| 86 |
+
const controller = new AbortController();
|
| 87 |
+
const body: ChatBody = {
|
| 88 |
+
inputCode,
|
| 89 |
+
model,
|
| 90 |
+
apiKey,
|
| 91 |
+
};
|
| 92 |
+
|
| 93 |
+
// -------------- Fetch --------------
|
| 94 |
+
const response = await fetch('/api/chatAPI', {
|
| 95 |
+
method: 'POST',
|
| 96 |
+
headers: {
|
| 97 |
+
'Content-Type': 'application/json',
|
| 98 |
+
},
|
| 99 |
+
signal: controller.signal,
|
| 100 |
+
body: JSON.stringify(body),
|
| 101 |
+
});
|
| 102 |
+
|
| 103 |
+
if (!response.ok) {
|
| 104 |
+
setLoading(false);
|
| 105 |
+
if (response) {
|
| 106 |
+
alert(
|
| 107 |
+
'Something went wrong went fetching from the API. Make sure to use a valid API key.',
|
| 108 |
+
);
|
| 109 |
+
}
|
| 110 |
+
return;
|
| 111 |
+
}
|
| 112 |
+
|
| 113 |
+
const data = response.body;
|
| 114 |
+
|
| 115 |
+
if (!data) {
|
| 116 |
+
setLoading(false);
|
| 117 |
+
alert('Something went wrong');
|
| 118 |
+
return;
|
| 119 |
+
}
|
| 120 |
+
|
| 121 |
+
const reader = data.getReader();
|
| 122 |
+
const decoder = new TextDecoder();
|
| 123 |
+
let done = false;
|
| 124 |
+
|
| 125 |
+
while (!done) {
|
| 126 |
+
setLoading(true);
|
| 127 |
+
const { value, done: doneReading } = await reader.read();
|
| 128 |
+
done = doneReading;
|
| 129 |
+
const chunkValue = decoder.decode(value);
|
| 130 |
+
setOutputCode((prevCode) => prevCode + chunkValue);
|
| 131 |
+
}
|
| 132 |
+
|
| 133 |
+
setLoading(false);
|
| 134 |
+
};
|
| 135 |
+
// -------------- Copy Response --------------
|
| 136 |
+
// const copyToClipboard = (text: string) => {
|
| 137 |
+
// const el = document.createElement('textarea');
|
| 138 |
+
// el.value = text;
|
| 139 |
+
// document.body.appendChild(el);
|
| 140 |
+
// el.select();
|
| 141 |
+
// document.execCommand('copy');
|
| 142 |
+
// document.body.removeChild(el);
|
| 143 |
+
// };
|
| 144 |
+
|
| 145 |
+
// *** Initializing apiKey with .env.local value
|
| 146 |
+
// useEffect(() => {
|
| 147 |
+
// ENV file verison
|
| 148 |
+
// const apiKeyENV = process.env.NEXT_PUBLIC_OPENAI_API_KEY
|
| 149 |
+
// if (apiKey === undefined || null) {
|
| 150 |
+
// setApiKey(apiKeyENV)
|
| 151 |
+
// }
|
| 152 |
+
// }, [])
|
| 153 |
+
|
| 154 |
+
const handleChange = (Event: any) => {
|
| 155 |
+
setInputCode(Event.target.value);
|
| 156 |
+
};
|
| 157 |
+
|
| 158 |
+
return (
|
| 159 |
+
<Flex
|
| 160 |
+
w="100%"
|
| 161 |
+
pt={{ base: '70px', md: '0px' }}
|
| 162 |
+
direction="column"
|
| 163 |
+
position="relative"
|
| 164 |
+
>
|
| 165 |
+
<Img
|
| 166 |
+
src={Bg.src}
|
| 167 |
+
position={'absolute'}
|
| 168 |
+
w="350px"
|
| 169 |
+
left="50%"
|
| 170 |
+
top="50%"
|
| 171 |
+
transform={'translate(-50%, -50%)'}
|
| 172 |
+
/>
|
| 173 |
+
<Flex
|
| 174 |
+
direction="column"
|
| 175 |
+
mx="auto"
|
| 176 |
+
w={{ base: '100%', md: '100%', xl: '100%' }}
|
| 177 |
+
minH={{ base: '75vh', '2xl': '85vh' }}
|
| 178 |
+
maxW="1000px"
|
| 179 |
+
>
|
| 180 |
+
{/* Model Change */}
|
| 181 |
+
<Flex direction={'column'} w="100%" mb={outputCode ? '20px' : 'auto'}>
|
| 182 |
+
<Flex
|
| 183 |
+
mx="auto"
|
| 184 |
+
zIndex="2"
|
| 185 |
+
w="max-content"
|
| 186 |
+
mb="20px"
|
| 187 |
+
borderRadius="60px"
|
| 188 |
+
>
|
| 189 |
+
<Flex
|
| 190 |
+
cursor={'pointer'}
|
| 191 |
+
transition="0.3s"
|
| 192 |
+
justify={'center'}
|
| 193 |
+
align="center"
|
| 194 |
+
bg={model === 'gpt-3.5-turbo' ? buttonBg : 'transparent'}
|
| 195 |
+
w="174px"
|
| 196 |
+
h="70px"
|
| 197 |
+
boxShadow={model === 'gpt-3.5-turbo' ? buttonShadow : 'none'}
|
| 198 |
+
borderRadius="14px"
|
| 199 |
+
color={textColor}
|
| 200 |
+
fontSize="18px"
|
| 201 |
+
fontWeight={'700'}
|
| 202 |
+
onClick={() => setModel('gpt-3.5-turbo')}
|
| 203 |
+
>
|
| 204 |
+
<Flex
|
| 205 |
+
borderRadius="full"
|
| 206 |
+
justify="center"
|
| 207 |
+
align="center"
|
| 208 |
+
bg={bgIcon}
|
| 209 |
+
me="10px"
|
| 210 |
+
h="39px"
|
| 211 |
+
w="39px"
|
| 212 |
+
>
|
| 213 |
+
<Icon
|
| 214 |
+
as={MdAutoAwesome}
|
| 215 |
+
width="20px"
|
| 216 |
+
height="20px"
|
| 217 |
+
color={iconColor}
|
| 218 |
+
/>
|
| 219 |
+
</Flex>
|
| 220 |
+
GPT-3.5
|
| 221 |
+
</Flex>
|
| 222 |
+
<Flex
|
| 223 |
+
cursor={'pointer'}
|
| 224 |
+
transition="0.3s"
|
| 225 |
+
justify={'center'}
|
| 226 |
+
align="center"
|
| 227 |
+
bg={model === 'gpt-4' ? buttonBg : 'transparent'}
|
| 228 |
+
w="164px"
|
| 229 |
+
h="70px"
|
| 230 |
+
boxShadow={model === 'gpt-4' ? buttonShadow : 'none'}
|
| 231 |
+
borderRadius="14px"
|
| 232 |
+
color={textColor}
|
| 233 |
+
fontSize="18px"
|
| 234 |
+
fontWeight={'700'}
|
| 235 |
+
onClick={() => setModel('gpt-4')}
|
| 236 |
+
>
|
| 237 |
+
<Flex
|
| 238 |
+
borderRadius="full"
|
| 239 |
+
justify="center"
|
| 240 |
+
align="center"
|
| 241 |
+
bg={bgIcon}
|
| 242 |
+
me="10px"
|
| 243 |
+
h="39px"
|
| 244 |
+
w="39px"
|
| 245 |
+
>
|
| 246 |
+
<Icon
|
| 247 |
+
as={MdBolt}
|
| 248 |
+
width="20px"
|
| 249 |
+
height="20px"
|
| 250 |
+
color={iconColor}
|
| 251 |
+
/>
|
| 252 |
+
</Flex>
|
| 253 |
+
GPT-4
|
| 254 |
+
</Flex>
|
| 255 |
+
</Flex>
|
| 256 |
+
|
| 257 |
+
<Accordion color={gray} allowToggle w="100%" my="0px" mx="auto">
|
| 258 |
+
<AccordionItem border="none">
|
| 259 |
+
<AccordionButton
|
| 260 |
+
borderBottom="0px solid"
|
| 261 |
+
maxW="max-content"
|
| 262 |
+
mx="auto"
|
| 263 |
+
_hover={{ border: '0px solid', bg: 'none' }}
|
| 264 |
+
_focus={{ border: '0px solid', bg: 'none' }}
|
| 265 |
+
>
|
| 266 |
+
<Box flex="1" textAlign="left">
|
| 267 |
+
<Text color={gray} fontWeight="500" fontSize="sm">
|
| 268 |
+
No plugins added
|
| 269 |
+
</Text>
|
| 270 |
+
</Box>
|
| 271 |
+
<AccordionIcon color={gray} />
|
| 272 |
+
</AccordionButton>
|
| 273 |
+
<AccordionPanel mx="auto" w="max-content" p="0px 0px 10px 0px">
|
| 274 |
+
<Text
|
| 275 |
+
color={gray}
|
| 276 |
+
fontWeight="500"
|
| 277 |
+
fontSize="sm"
|
| 278 |
+
textAlign={'center'}
|
| 279 |
+
>
|
| 280 |
+
This is a cool text example.
|
| 281 |
+
</Text>
|
| 282 |
+
</AccordionPanel>
|
| 283 |
+
</AccordionItem>
|
| 284 |
+
</Accordion>
|
| 285 |
+
</Flex>
|
| 286 |
+
{/* Main Box */}
|
| 287 |
+
<Flex
|
| 288 |
+
direction="column"
|
| 289 |
+
w="100%"
|
| 290 |
+
mx="auto"
|
| 291 |
+
display={outputCode ? 'flex' : 'none'}
|
| 292 |
+
mb={'auto'}
|
| 293 |
+
>
|
| 294 |
+
<Flex w="100%" align={'center'} mb="10px">
|
| 295 |
+
<Flex
|
| 296 |
+
borderRadius="full"
|
| 297 |
+
justify="center"
|
| 298 |
+
align="center"
|
| 299 |
+
bg={'transparent'}
|
| 300 |
+
border="1px solid"
|
| 301 |
+
borderColor={borderColor}
|
| 302 |
+
me="20px"
|
| 303 |
+
h="40px"
|
| 304 |
+
minH="40px"
|
| 305 |
+
minW="40px"
|
| 306 |
+
>
|
| 307 |
+
<Icon
|
| 308 |
+
as={MdPerson}
|
| 309 |
+
width="20px"
|
| 310 |
+
height="20px"
|
| 311 |
+
color={brandColor}
|
| 312 |
+
/>
|
| 313 |
+
</Flex>
|
| 314 |
+
<Flex
|
| 315 |
+
p="22px"
|
| 316 |
+
border="1px solid"
|
| 317 |
+
borderColor={borderColor}
|
| 318 |
+
borderRadius="14px"
|
| 319 |
+
w="100%"
|
| 320 |
+
zIndex={'2'}
|
| 321 |
+
>
|
| 322 |
+
<Text
|
| 323 |
+
color={textColor}
|
| 324 |
+
fontWeight="600"
|
| 325 |
+
fontSize={{ base: 'sm', md: 'md' }}
|
| 326 |
+
lineHeight={{ base: '24px', md: '26px' }}
|
| 327 |
+
>
|
| 328 |
+
{inputOnSubmit}
|
| 329 |
+
</Text>
|
| 330 |
+
<Icon
|
| 331 |
+
cursor="pointer"
|
| 332 |
+
as={MdEdit}
|
| 333 |
+
ms="auto"
|
| 334 |
+
width="20px"
|
| 335 |
+
height="20px"
|
| 336 |
+
color={gray}
|
| 337 |
+
/>
|
| 338 |
+
</Flex>
|
| 339 |
+
</Flex>
|
| 340 |
+
<Flex w="100%">
|
| 341 |
+
<Flex
|
| 342 |
+
borderRadius="full"
|
| 343 |
+
justify="center"
|
| 344 |
+
align="center"
|
| 345 |
+
bg={'linear-gradient(15.46deg, #4A25E1 26.3%, #7B5AFF 86.4%)'}
|
| 346 |
+
me="20px"
|
| 347 |
+
h="40px"
|
| 348 |
+
minH="40px"
|
| 349 |
+
minW="40px"
|
| 350 |
+
>
|
| 351 |
+
<Icon
|
| 352 |
+
as={MdAutoAwesome}
|
| 353 |
+
width="20px"
|
| 354 |
+
height="20px"
|
| 355 |
+
color="white"
|
| 356 |
+
/>
|
| 357 |
+
</Flex>
|
| 358 |
+
<MessageBoxChat output={outputCode} />
|
| 359 |
+
</Flex>
|
| 360 |
+
</Flex>
|
| 361 |
+
{/* Chat Input */}
|
| 362 |
+
<Flex
|
| 363 |
+
ms={{ base: '0px', xl: '60px' }}
|
| 364 |
+
mt="20px"
|
| 365 |
+
justifySelf={'flex-end'}
|
| 366 |
+
>
|
| 367 |
+
<Input
|
| 368 |
+
minH="54px"
|
| 369 |
+
h="100%"
|
| 370 |
+
border="1px solid"
|
| 371 |
+
borderColor={borderColor}
|
| 372 |
+
borderRadius="45px"
|
| 373 |
+
p="15px 20px"
|
| 374 |
+
me="10px"
|
| 375 |
+
fontSize="sm"
|
| 376 |
+
fontWeight="500"
|
| 377 |
+
_focus={{ borderColor: 'none' }}
|
| 378 |
+
color={inputColor}
|
| 379 |
+
_placeholder={placeholderColor}
|
| 380 |
+
placeholder="Type your message here..."
|
| 381 |
+
onChange={handleChange}
|
| 382 |
+
/>
|
| 383 |
+
<Button
|
| 384 |
+
variant="primary"
|
| 385 |
+
py="20px"
|
| 386 |
+
px="16px"
|
| 387 |
+
fontSize="sm"
|
| 388 |
+
borderRadius="45px"
|
| 389 |
+
ms="auto"
|
| 390 |
+
w={{ base: '160px', md: '210px' }}
|
| 391 |
+
h="54px"
|
| 392 |
+
_hover={{
|
| 393 |
+
boxShadow:
|
| 394 |
+
'0px 21px 27px -10px rgba(96, 60, 255, 0.48) !important',
|
| 395 |
+
bg:
|
| 396 |
+
'linear-gradient(15.46deg, #4A25E1 26.3%, #7B5AFF 86.4%) !important',
|
| 397 |
+
_disabled: {
|
| 398 |
+
bg: 'linear-gradient(15.46deg, #4A25E1 26.3%, #7B5AFF 86.4%)',
|
| 399 |
+
},
|
| 400 |
+
}}
|
| 401 |
+
onClick={handleTranslate}
|
| 402 |
+
isLoading={loading ? true : false}
|
| 403 |
+
>
|
| 404 |
+
Submit
|
| 405 |
+
</Button>
|
| 406 |
+
</Flex>
|
| 407 |
+
|
| 408 |
+
<Flex
|
| 409 |
+
justify="center"
|
| 410 |
+
mt="20px"
|
| 411 |
+
direction={{ base: 'column', md: 'row' }}
|
| 412 |
+
alignItems="center"
|
| 413 |
+
>
|
| 414 |
+
<Text fontSize="xs" textAlign="center" color={gray}>
|
| 415 |
+
Free Research Preview. ChatGPT may produce inaccurate information
|
| 416 |
+
about people, places, or facts.
|
| 417 |
+
</Text>
|
| 418 |
+
<Link href="https://help.openai.com/en/articles/6825453-chatgpt-release-notes">
|
| 419 |
+
<Text
|
| 420 |
+
fontSize="xs"
|
| 421 |
+
color={textColor}
|
| 422 |
+
fontWeight="500"
|
| 423 |
+
textDecoration="underline"
|
| 424 |
+
>
|
| 425 |
+
ChatGPT May 12 Version
|
| 426 |
+
</Text>
|
| 427 |
+
</Link>
|
| 428 |
+
</Flex>
|
| 429 |
+
</Flex>
|
| 430 |
+
</Flex>
|
| 431 |
+
);
|
| 432 |
+
}
|
prettier.config.js
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
module.exports = {
|
| 2 |
+
trailingComma: 'all',
|
| 3 |
+
singleQuote: true,
|
| 4 |
+
};
|
public/favicon.ico
ADDED
|
|
public/fonts/dm-sans/DMSans-Bold.ttf
ADDED
|
Binary file (71.9 kB). View file
|
|
|
public/fonts/dm-sans/DMSans-BoldItalic.ttf
ADDED
|
Binary file (73.4 kB). View file
|
|
|
public/fonts/dm-sans/DMSans-Italic.ttf
ADDED
|
Binary file (73.6 kB). View file
|
|
|
public/fonts/dm-sans/DMSans-Medium.ttf
ADDED
|
Binary file (71.8 kB). View file
|
|
|
public/fonts/dm-sans/DMSans-MediumItalic.ttf
ADDED
|
Binary file (73.3 kB). View file
|
|
|
public/fonts/dm-sans/DMSans-Regular.ttf
ADDED
|
Binary file (72 kB). View file
|
|
|
public/fonts/dm-sans/OFL.txt
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Copyright 2014-2017 Indian Type Foundry (info@indiantypefoundry.com). Copyright 2019 Google LLC.
|
| 2 |
+
|
| 3 |
+
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
| 4 |
+
This license is copied below, and is also available with a FAQ at:
|
| 5 |
+
http://scripts.sil.org/OFL
|
| 6 |
+
|
| 7 |
+
|
| 8 |
+
-----------------------------------------------------------
|
| 9 |
+
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
| 10 |
+
-----------------------------------------------------------
|
| 11 |
+
|
| 12 |
+
PREAMBLE
|
| 13 |
+
The goals of the Open Font License (OFL) are to stimulate worldwide
|
| 14 |
+
development of collaborative font projects, to support the font creation
|
| 15 |
+
efforts of academic and linguistic communities, and to provide a free and
|
| 16 |
+
open framework in which fonts may be shared and improved in partnership
|
| 17 |
+
with others.
|
| 18 |
+
|
| 19 |
+
The OFL allows the licensed fonts to be used, studied, modified and
|
| 20 |
+
redistributed freely as long as they are not sold by themselves. The
|
| 21 |
+
fonts, including any derivative works, can be bundled, embedded,
|
| 22 |
+
redistributed and/or sold with any software provided that any reserved
|
| 23 |
+
names are not used by derivative works. The fonts and derivatives,
|
| 24 |
+
however, cannot be released under any other type of license. The
|
| 25 |
+
requirement for fonts to remain under this license does not apply
|
| 26 |
+
to any document created using the fonts or their derivatives.
|
| 27 |
+
|
| 28 |
+
DEFINITIONS
|
| 29 |
+
"Font Software" refers to the set of files released by the Copyright
|
| 30 |
+
Holder(s) under this license and clearly marked as such. This may
|
| 31 |
+
include source files, build scripts and documentation.
|
| 32 |
+
|
| 33 |
+
"Reserved Font Name" refers to any names specified as such after the
|
| 34 |
+
copyright statement(s).
|
| 35 |
+
|
| 36 |
+
"Original Version" refers to the collection of Font Software components as
|
| 37 |
+
distributed by the Copyright Holder(s).
|
| 38 |
+
|
| 39 |
+
"Modified Version" refers to any derivative made by adding to, deleting,
|
| 40 |
+
or substituting -- in part or in whole -- any of the components of the
|
| 41 |
+
Original Version, by changing formats or by porting the Font Software to a
|
| 42 |
+
new environment.
|
| 43 |
+
|
| 44 |
+
"Author" refers to any designer, engineer, programmer, technical
|
| 45 |
+
writer or other person who contributed to the Font Software.
|
| 46 |
+
|
| 47 |
+
PERMISSION & CONDITIONS
|
| 48 |
+
Permission is hereby granted, free of charge, to any person obtaining
|
| 49 |
+
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
| 50 |
+
redistribute, and sell modified and unmodified copies of the Font
|
| 51 |
+
Software, subject to the following conditions:
|
| 52 |
+
|
| 53 |
+
1) Neither the Font Software nor any of its individual components,
|
| 54 |
+
in Original or Modified Versions, may be sold by itself.
|
| 55 |
+
|
| 56 |
+
2) Original or Modified Versions of the Font Software may be bundled,
|
| 57 |
+
redistributed and/or sold with any software, provided that each copy
|
| 58 |
+
contains the above copyright notice and this license. These can be
|
| 59 |
+
included either as stand-alone text files, human-readable headers or
|
| 60 |
+
in the appropriate machine-readable metadata fields within text or
|
| 61 |
+
binary files as long as those fields can be easily viewed by the user.
|
| 62 |
+
|
| 63 |
+
3) No Modified Version of the Font Software may use the Reserved Font
|
| 64 |
+
Name(s) unless explicit written permission is granted by the corresponding
|
| 65 |
+
Copyright Holder. This restriction only applies to the primary font name as
|
| 66 |
+
presented to the users.
|
| 67 |
+
|
| 68 |
+
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
| 69 |
+
Software shall not be used to promote, endorse or advertise any
|
| 70 |
+
Modified Version, except to acknowledge the contribution(s) of the
|
| 71 |
+
Copyright Holder(s) and the Author(s) or with their explicit written
|
| 72 |
+
permission.
|
| 73 |
+
|
| 74 |
+
5) The Font Software, modified or unmodified, in part or in whole,
|
| 75 |
+
must be distributed entirely under this license, and must not be
|
| 76 |
+
distributed under any other license. The requirement for fonts to
|
| 77 |
+
remain under this license does not apply to any document created
|
| 78 |
+
using the Font Software.
|
| 79 |
+
|
| 80 |
+
TERMINATION
|
| 81 |
+
This license becomes null and void if any of the above conditions are
|
| 82 |
+
not met.
|
| 83 |
+
|
| 84 |
+
DISCLAIMER
|
| 85 |
+
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
| 86 |
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
| 87 |
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
| 88 |
+
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
| 89 |
+
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
| 90 |
+
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
| 91 |
+
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
| 92 |
+
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
| 93 |
+
OTHER DEALINGS IN THE FONT SOFTWARE.
|
public/img/avatars/avatar1.png
ADDED
|
|
public/img/avatars/avatar10.png
ADDED
|
|
public/img/avatars/avatar2.png
ADDED
|
|
public/img/avatars/avatar3.png
ADDED
|
|
public/img/avatars/avatar4.png
ADDED
|
|
public/img/avatars/avatar5.png
ADDED
|
|
public/img/avatars/avatar6.png
ADDED
|
|
public/img/avatars/avatar7.png
ADDED
|
|
public/img/avatars/avatar8.png
ADDED
|
|
public/img/avatars/avatar9.png
ADDED
|
|
public/img/avatars/avatarSimmmple.png
ADDED
|
|
public/img/chat/bg-image.png
ADDED
|
public/img/layout/Navbar.png
ADDED
|
public/img/layout/logoWhite.png
ADDED
|
public/img/plan/InvoiceBg.png
ADDED
|
public/manifest.json
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"short_name": "React App",
|
| 3 |
+
"name": "Create React App Sample",
|
| 4 |
+
"icons": [
|
| 5 |
+
{
|
| 6 |
+
"src": "favicon.ico",
|
| 7 |
+
"sizes": "64x64 32x32 24x24 16x16",
|
| 8 |
+
"type": "image/x-icon"
|
| 9 |
+
}
|
| 10 |
+
],
|
| 11 |
+
"start_url": ".",
|
| 12 |
+
"display": "standalone",
|
| 13 |
+
"theme_color": "#000000",
|
| 14 |
+
"background_color": "#ffffff"
|
| 15 |
+
}
|
public/robots.txt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
User-Agent: *
|
| 2 |
+
Disallow:
|
| 3 |
+
Sitemap: https://horizon-ui.com
|
src/components/CodeBlock.tsx
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { StreamLanguage } from '@codemirror/language';
|
| 2 |
+
import { go } from '@codemirror/legacy-modes/mode/go';
|
| 3 |
+
import { tokyoNight } from '@uiw/codemirror-theme-tokyo-night';
|
| 4 |
+
import CodeMirror from '@uiw/react-codemirror';
|
| 5 |
+
import { FC, useEffect, useState } from 'react';
|
| 6 |
+
|
| 7 |
+
interface Props {
|
| 8 |
+
code: string;
|
| 9 |
+
height: string;
|
| 10 |
+
editable?: boolean;
|
| 11 |
+
onChange?: (value: string) => void;
|
| 12 |
+
}
|
| 13 |
+
|
| 14 |
+
export const CodeBlock: FC<Props> = ({
|
| 15 |
+
height,
|
| 16 |
+
code,
|
| 17 |
+
editable = false,
|
| 18 |
+
onChange = () => {},
|
| 19 |
+
}) => {
|
| 20 |
+
const [copyText, setCopyText] = useState<string>('Copy');
|
| 21 |
+
|
| 22 |
+
useEffect(() => {
|
| 23 |
+
const timeout = setTimeout(() => {
|
| 24 |
+
setCopyText('Copy');
|
| 25 |
+
}, 2000);
|
| 26 |
+
|
| 27 |
+
return () => clearTimeout(timeout);
|
| 28 |
+
}, [copyText]);
|
| 29 |
+
|
| 30 |
+
return (
|
| 31 |
+
<div className={`relative h-${height}px overflow-scroll`}>
|
| 32 |
+
<button
|
| 33 |
+
className="absolute right-0 top-0 z-10 rounded bg-[#1A1B26] p-1 text-xs text-white hover:bg-[#2D2E3A] active:bg-[#2D2E3A]"
|
| 34 |
+
onClick={() => {
|
| 35 |
+
navigator.clipboard.writeText(code);
|
| 36 |
+
setCopyText('Copied!');
|
| 37 |
+
}}
|
| 38 |
+
>
|
| 39 |
+
{copyText}
|
| 40 |
+
</button>
|
| 41 |
+
<CodeMirror
|
| 42 |
+
editable={editable}
|
| 43 |
+
value={code}
|
| 44 |
+
minHeight={`${height}px`}
|
| 45 |
+
className="rounded-md overflow-scroll"
|
| 46 |
+
extensions={[StreamLanguage.define(go)]}
|
| 47 |
+
theme={tokyoNight}
|
| 48 |
+
onChange={(value) => onChange(value)}
|
| 49 |
+
/>
|
| 50 |
+
</div>
|
| 51 |
+
);
|
| 52 |
+
};
|
src/components/MarkdownBlock.tsx
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import ReactMarkdown from 'react-markdown';
|
| 2 |
+
import { FC, useEffect, useState } from 'react';
|
| 3 |
+
|
| 4 |
+
interface Props {
|
| 5 |
+
code: string;
|
| 6 |
+
editable?: boolean;
|
| 7 |
+
onChange?: (value: string) => void;
|
| 8 |
+
}
|
| 9 |
+
|
| 10 |
+
export const MarkdownBlock: FC<Props> = ({
|
| 11 |
+
code,
|
| 12 |
+
editable = false,
|
| 13 |
+
onChange = () => {},
|
| 14 |
+
}) => {
|
| 15 |
+
const [copyText, setCopyText] = useState<string>('Copy');
|
| 16 |
+
|
| 17 |
+
useEffect(() => {
|
| 18 |
+
const timeout = setTimeout(() => {
|
| 19 |
+
setCopyText('Copy');
|
| 20 |
+
}, 2000);
|
| 21 |
+
|
| 22 |
+
return () => clearTimeout(timeout);
|
| 23 |
+
}, [copyText]);
|
| 24 |
+
|
| 25 |
+
return (
|
| 26 |
+
<div className="relative">
|
| 27 |
+
<button
|
| 28 |
+
className="absolute right-0 top-0 z-10 rounded bg-[#1A1B26] p-1 text-xs text-white hover:bg-[#2D2E3A] active:bg-[#2D2E3A]"
|
| 29 |
+
onClick={() => {
|
| 30 |
+
navigator.clipboard.writeText(code);
|
| 31 |
+
setCopyText('Copied!');
|
| 32 |
+
}}
|
| 33 |
+
>
|
| 34 |
+
{copyText}
|
| 35 |
+
</button>
|
| 36 |
+
|
| 37 |
+
<div className="p-4 h-500px bg-[#1A1B26] text-white overflow-scroll rounded-md">
|
| 38 |
+
<ReactMarkdown className="font-normal">{code}</ReactMarkdown>
|
| 39 |
+
</div>
|
| 40 |
+
</div>
|
| 41 |
+
);
|
| 42 |
+
};
|
src/components/MessageBox.tsx
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import ReactMarkdown from 'react-markdown'
|
| 2 |
+
import { useColorModeValue } from '@chakra-ui/react'
|
| 3 |
+
import Card from '@/components/card/Card'
|
| 4 |
+
|
| 5 |
+
export default function MessageBox(props: { output: string }) {
|
| 6 |
+
const { output } = props
|
| 7 |
+
const textColor = useColorModeValue('navy.700', 'white')
|
| 8 |
+
return (
|
| 9 |
+
<Card
|
| 10 |
+
display={output ? 'flex' : 'none'}
|
| 11 |
+
px="22px !important"
|
| 12 |
+
pl="22px !important"
|
| 13 |
+
color={textColor}
|
| 14 |
+
minH="450px"
|
| 15 |
+
fontSize={{ base: 'sm', md: 'md' }}
|
| 16 |
+
lineHeight={{ base: '24px', md: '26px' }}
|
| 17 |
+
fontWeight="500"
|
| 18 |
+
>
|
| 19 |
+
<ReactMarkdown className="font-medium">
|
| 20 |
+
{output ? output : ''}
|
| 21 |
+
</ReactMarkdown>
|
| 22 |
+
</Card>
|
| 23 |
+
)
|
| 24 |
+
}
|
src/components/apiModal/index.tsx
ADDED
|
@@ -0,0 +1,253 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
'use client';
|
| 2 |
+
import Card from '@/components/card/Card';
|
| 3 |
+
import {
|
| 4 |
+
Accordion,
|
| 5 |
+
AccordionItem,
|
| 6 |
+
AccordionButton,
|
| 7 |
+
AccordionPanel,
|
| 8 |
+
AccordionIcon,
|
| 9 |
+
Box,
|
| 10 |
+
Button,
|
| 11 |
+
Flex,
|
| 12 |
+
Icon,
|
| 13 |
+
Input,
|
| 14 |
+
Link,
|
| 15 |
+
ListItem,
|
| 16 |
+
UnorderedList,
|
| 17 |
+
Modal,
|
| 18 |
+
ModalBody,
|
| 19 |
+
ModalCloseButton,
|
| 20 |
+
ModalContent,
|
| 21 |
+
ModalHeader,
|
| 22 |
+
ModalOverlay,
|
| 23 |
+
Text,
|
| 24 |
+
useColorModeValue,
|
| 25 |
+
useDisclosure,
|
| 26 |
+
useToast,
|
| 27 |
+
} from '@chakra-ui/react';
|
| 28 |
+
import { useState } from 'react';
|
| 29 |
+
import { MdLock } from 'react-icons/md';
|
| 30 |
+
|
| 31 |
+
function APIModal(props: { setApiKey: any; sidebar?: boolean }) {
|
| 32 |
+
const { setApiKey, sidebar } = props;
|
| 33 |
+
const { isOpen, onOpen, onClose } = useDisclosure();
|
| 34 |
+
const [inputCode, setInputCode] = useState<string>('');
|
| 35 |
+
|
| 36 |
+
const textColor = useColorModeValue('navy.700', 'white');
|
| 37 |
+
const grayColor = useColorModeValue('gray.500', 'gray.500');
|
| 38 |
+
const inputBorder = useColorModeValue('gray.200', 'whiteAlpha.200');
|
| 39 |
+
const inputColor = useColorModeValue('navy.700', 'white');
|
| 40 |
+
const link = useColorModeValue('brand.500', 'white');
|
| 41 |
+
const navbarIcon = useColorModeValue('gray.500', 'white');
|
| 42 |
+
const toast = useToast();
|
| 43 |
+
|
| 44 |
+
const handleChange = (Event: any) => {
|
| 45 |
+
setInputCode(Event.target.value);
|
| 46 |
+
};
|
| 47 |
+
|
| 48 |
+
const handleApiKeyChange = (value: string) => {
|
| 49 |
+
setApiKey(value);
|
| 50 |
+
|
| 51 |
+
localStorage.setItem('apiKey', value);
|
| 52 |
+
};
|
| 53 |
+
return (
|
| 54 |
+
<>
|
| 55 |
+
{sidebar ? (
|
| 56 |
+
<Button
|
| 57 |
+
onClick={onOpen}
|
| 58 |
+
display="flex"
|
| 59 |
+
variant="api"
|
| 60 |
+
fontSize={'sm'}
|
| 61 |
+
fontWeight="600"
|
| 62 |
+
borderRadius={'45px'}
|
| 63 |
+
mt="8px"
|
| 64 |
+
minH="40px"
|
| 65 |
+
>
|
| 66 |
+
Set API Key
|
| 67 |
+
</Button>
|
| 68 |
+
) : (
|
| 69 |
+
<Button
|
| 70 |
+
onClick={onOpen}
|
| 71 |
+
minW="max-content !important"
|
| 72 |
+
p="0px"
|
| 73 |
+
me="10px"
|
| 74 |
+
_hover={{ bg: 'none' }}
|
| 75 |
+
_focus={{ bg: 'none' }}
|
| 76 |
+
_selected={{ bg: 'none' }}
|
| 77 |
+
bg="none !important"
|
| 78 |
+
>
|
| 79 |
+
<Icon w="18px" h="18px" as={MdLock} color={navbarIcon} />
|
| 80 |
+
</Button>
|
| 81 |
+
)}
|
| 82 |
+
|
| 83 |
+
<Modal blockScrollOnMount={false} isOpen={isOpen} onClose={onClose}>
|
| 84 |
+
<ModalOverlay />
|
| 85 |
+
<ModalContent bg="none" boxShadow="none">
|
| 86 |
+
<Card textAlign={'center'}>
|
| 87 |
+
<ModalHeader
|
| 88 |
+
fontSize="22px"
|
| 89 |
+
fontWeight={'700'}
|
| 90 |
+
mx="auto"
|
| 91 |
+
textAlign={'center'}
|
| 92 |
+
color={textColor}
|
| 93 |
+
>
|
| 94 |
+
Enter your OpenAI API Key
|
| 95 |
+
</ModalHeader>
|
| 96 |
+
<ModalCloseButton _focus={{ boxShadow: 'none' }} />
|
| 97 |
+
<ModalBody p="0px">
|
| 98 |
+
<Text
|
| 99 |
+
color={grayColor}
|
| 100 |
+
fontWeight="500"
|
| 101 |
+
fontSize="md"
|
| 102 |
+
lineHeight="28px"
|
| 103 |
+
mb="22px"
|
| 104 |
+
>
|
| 105 |
+
You need an OpenAI API Key to use Horizon AI Template's
|
| 106 |
+
features. Your API Key is stored locally on your browser and
|
| 107 |
+
never sent anywhere else.
|
| 108 |
+
</Text>
|
| 109 |
+
<Flex mb="20px">
|
| 110 |
+
<Input
|
| 111 |
+
h="100%"
|
| 112 |
+
border="1px solid"
|
| 113 |
+
borderColor={inputBorder}
|
| 114 |
+
borderRadius="45px"
|
| 115 |
+
p="15px 20px"
|
| 116 |
+
me="10px"
|
| 117 |
+
fontSize="sm"
|
| 118 |
+
fontWeight="500"
|
| 119 |
+
_focus={{ borderColor: 'none' }}
|
| 120 |
+
_placeholder={{ color: 'gray.500' }}
|
| 121 |
+
color={inputColor}
|
| 122 |
+
placeholder="sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
| 123 |
+
onChange={handleChange}
|
| 124 |
+
value={inputCode}
|
| 125 |
+
/>
|
| 126 |
+
<Button
|
| 127 |
+
variant="chakraLinear"
|
| 128 |
+
py="20px"
|
| 129 |
+
px="16px"
|
| 130 |
+
fontSize="sm"
|
| 131 |
+
borderRadius="45px"
|
| 132 |
+
ms="auto"
|
| 133 |
+
mb={{ base: '20px', md: '0px' }}
|
| 134 |
+
w={{ base: '300px', md: '180px' }}
|
| 135 |
+
h="54px"
|
| 136 |
+
onClick={() => {
|
| 137 |
+
inputCode?.includes('sk-')
|
| 138 |
+
? handleApiKeyChange(inputCode)
|
| 139 |
+
: null;
|
| 140 |
+
if (inputCode)
|
| 141 |
+
toast({
|
| 142 |
+
title: inputCode?.includes('sk-')
|
| 143 |
+
? `Success! You have successfully added your API key!`
|
| 144 |
+
: !inputCode?.includes('sk-')
|
| 145 |
+
? `Invalid API key. Please make sure your API key is still working properly.`
|
| 146 |
+
: 'Please add your API key!',
|
| 147 |
+
position: 'top',
|
| 148 |
+
status: inputCode?.includes('sk-')
|
| 149 |
+
? 'success'
|
| 150 |
+
: !inputCode?.includes('sk-')
|
| 151 |
+
? `error`
|
| 152 |
+
: !inputCode
|
| 153 |
+
? 'warning'
|
| 154 |
+
: 'error',
|
| 155 |
+
isClosable: true,
|
| 156 |
+
});
|
| 157 |
+
}}
|
| 158 |
+
>
|
| 159 |
+
Save API Key
|
| 160 |
+
</Button>
|
| 161 |
+
</Flex>
|
| 162 |
+
<Link
|
| 163 |
+
color={link}
|
| 164 |
+
fontSize="sm"
|
| 165 |
+
href="https://platform.openai.com/account/api-keys"
|
| 166 |
+
textDecoration="underline !important"
|
| 167 |
+
fontWeight="600"
|
| 168 |
+
>
|
| 169 |
+
Get your API key from Open AI Dashboard
|
| 170 |
+
</Link>
|
| 171 |
+
<Accordion allowToggle w="100%" my="16px">
|
| 172 |
+
<AccordionItem border="none">
|
| 173 |
+
<AccordionButton
|
| 174 |
+
borderBottom="0px solid"
|
| 175 |
+
maxW="max-content"
|
| 176 |
+
mx="auto"
|
| 177 |
+
_hover={{ border: '0px solid', bg: 'none' }}
|
| 178 |
+
_focus={{ border: '0px solid', bg: 'none' }}
|
| 179 |
+
>
|
| 180 |
+
<Box flex="1" textAlign="left">
|
| 181 |
+
<Text
|
| 182 |
+
color={textColor}
|
| 183 |
+
fontWeight="700"
|
| 184 |
+
fontSize={{ sm: 'md', lg: 'md' }}
|
| 185 |
+
>
|
| 186 |
+
Your API Key is not working?
|
| 187 |
+
</Text>
|
| 188 |
+
</Box>
|
| 189 |
+
<AccordionIcon color={textColor} />
|
| 190 |
+
</AccordionButton>
|
| 191 |
+
<AccordionPanel p="18px 0px 10px 0px">
|
| 192 |
+
<UnorderedList p="5px">
|
| 193 |
+
<ListItem
|
| 194 |
+
mb="26px"
|
| 195 |
+
color={grayColor}
|
| 196 |
+
fontSize=",d"
|
| 197 |
+
fontWeight="500"
|
| 198 |
+
>
|
| 199 |
+
Make sure you have an{' '}
|
| 200 |
+
<Link
|
| 201 |
+
textDecoration="underline"
|
| 202 |
+
fontSize=",d"
|
| 203 |
+
href="https://platform.openai.com/account/"
|
| 204 |
+
fontWeight="500"
|
| 205 |
+
color={grayColor}
|
| 206 |
+
>
|
| 207 |
+
OpenAI account
|
| 208 |
+
</Link>{' '}
|
| 209 |
+
and a valid API key to use ChatGPT. We don't sell API
|
| 210 |
+
keys.
|
| 211 |
+
</ListItem>
|
| 212 |
+
<ListItem
|
| 213 |
+
color={grayColor}
|
| 214 |
+
fontSize="md"
|
| 215 |
+
lineHeight="28px"
|
| 216 |
+
fontWeight="500"
|
| 217 |
+
>
|
| 218 |
+
Make sure you have your billing info added in{' '}
|
| 219 |
+
<Link
|
| 220 |
+
textDecoration="underline"
|
| 221 |
+
fontSize="md"
|
| 222 |
+
lineHeight="28px"
|
| 223 |
+
href="https://platform.openai.com/account/billing/overview"
|
| 224 |
+
fontWeight="500"
|
| 225 |
+
color={grayColor}
|
| 226 |
+
>
|
| 227 |
+
OpenAI Billing
|
| 228 |
+
</Link>{' '}
|
| 229 |
+
page. Without billing info, your API key will not work.
|
| 230 |
+
</ListItem>
|
| 231 |
+
</UnorderedList>
|
| 232 |
+
</AccordionPanel>
|
| 233 |
+
</AccordionItem>
|
| 234 |
+
</Accordion>
|
| 235 |
+
<Text
|
| 236 |
+
color={grayColor}
|
| 237 |
+
fontWeight="500"
|
| 238 |
+
fontSize="sm"
|
| 239 |
+
mb="42px"
|
| 240 |
+
mx="30px"
|
| 241 |
+
>
|
| 242 |
+
*The app will connect to OpenAI API server to check if your API
|
| 243 |
+
Key is working properly.
|
| 244 |
+
</Text>
|
| 245 |
+
</ModalBody>
|
| 246 |
+
</Card>
|
| 247 |
+
</ModalContent>
|
| 248 |
+
</Modal>
|
| 249 |
+
</>
|
| 250 |
+
);
|
| 251 |
+
}
|
| 252 |
+
|
| 253 |
+
export default APIModal;
|
src/components/card/Card.tsx
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
'use client';
|
| 2 |
+
import { useStyleConfig, chakra, forwardRef } from '@chakra-ui/react';
|
| 3 |
+
import { CustomCardProps } from '@/theme/theme';
|
| 4 |
+
const CustomCard = forwardRef<CustomCardProps, 'div'>((props, ref) => {
|
| 5 |
+
const { size, variant, ...rest } = props;
|
| 6 |
+
const styles = useStyleConfig('Card', { size, variant });
|
| 7 |
+
|
| 8 |
+
return <chakra.div ref={ref} __css={styles} {...rest} />;
|
| 9 |
+
});
|
| 10 |
+
|
| 11 |
+
export default CustomCard;
|
src/components/fields/InputField.tsx
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
'use client';
|
| 2 |
+
// Chakra imports
|
| 3 |
+
import {
|
| 4 |
+
Flex,
|
| 5 |
+
FormLabel,
|
| 6 |
+
Input,
|
| 7 |
+
Text,
|
| 8 |
+
useColorModeValue,
|
| 9 |
+
} from '@chakra-ui/react';
|
| 10 |
+
|
| 11 |
+
export default function Default(props: {
|
| 12 |
+
id?: string;
|
| 13 |
+
label?: string;
|
| 14 |
+
extra?: JSX.Element;
|
| 15 |
+
placeholder?: string;
|
| 16 |
+
type?: string;
|
| 17 |
+
[x: string]: any;
|
| 18 |
+
}) {
|
| 19 |
+
const { id, label, extra, placeholder, type, mb, ...rest } = props;
|
| 20 |
+
// Chakra Color Mode
|
| 21 |
+
const textColorPrimary = useColorModeValue('navy.700', 'white');
|
| 22 |
+
const searchColor = useColorModeValue('gray.700', 'white');
|
| 23 |
+
const inputBg = useColorModeValue('transparent', 'navy.800');
|
| 24 |
+
const placeholderColor = useColorModeValue(
|
| 25 |
+
{ color: 'gray.500' },
|
| 26 |
+
{ color: 'whiteAlpha.600' },
|
| 27 |
+
);
|
| 28 |
+
|
| 29 |
+
return (
|
| 30 |
+
<Flex direction="column" mb={mb ? mb : '30px'}>
|
| 31 |
+
<FormLabel
|
| 32 |
+
display="flex"
|
| 33 |
+
ms="10px"
|
| 34 |
+
htmlFor={id}
|
| 35 |
+
fontSize="sm"
|
| 36 |
+
color={textColorPrimary}
|
| 37 |
+
fontWeight="bold"
|
| 38 |
+
_hover={{ cursor: 'pointer' }}
|
| 39 |
+
>
|
| 40 |
+
{label}
|
| 41 |
+
<Text fontSize="sm" fontWeight="400" ms="2px">
|
| 42 |
+
{extra}
|
| 43 |
+
</Text>
|
| 44 |
+
</FormLabel>
|
| 45 |
+
<Input
|
| 46 |
+
{...rest}
|
| 47 |
+
type={type}
|
| 48 |
+
id={id}
|
| 49 |
+
fontWeight="500"
|
| 50 |
+
bg={inputBg}
|
| 51 |
+
variant="main"
|
| 52 |
+
fontSize="sm"
|
| 53 |
+
placeholder={placeholder}
|
| 54 |
+
_placeholder={placeholderColor}
|
| 55 |
+
border="1px solid"
|
| 56 |
+
color={searchColor}
|
| 57 |
+
borderColor={useColorModeValue('gray.200', 'whiteAlpha.100')}
|
| 58 |
+
borderRadius="12px"
|
| 59 |
+
h="44px"
|
| 60 |
+
maxH="44px"
|
| 61 |
+
/>
|
| 62 |
+
</Flex>
|
| 63 |
+
);
|
| 64 |
+
}
|
src/components/footer/FooterAdmin.tsx
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
'use client';
|
| 2 |
+
/*eslint-disable*/
|
| 3 |
+
|
| 4 |
+
import {
|
| 5 |
+
Flex,
|
| 6 |
+
List,
|
| 7 |
+
ListItem,
|
| 8 |
+
Text,
|
| 9 |
+
useColorModeValue,
|
| 10 |
+
} from '@chakra-ui/react';
|
| 11 |
+
import Link from '@/components/link/Link';
|
| 12 |
+
|
| 13 |
+
export default function Footer() {
|
| 14 |
+
const textColor = useColorModeValue('gray.500', 'white');
|
| 15 |
+
return (
|
| 16 |
+
<Flex
|
| 17 |
+
zIndex="3"
|
| 18 |
+
flexDirection={{
|
| 19 |
+
base: 'column',
|
| 20 |
+
xl: 'row',
|
| 21 |
+
}}
|
| 22 |
+
alignItems="center"
|
| 23 |
+
justifyContent="space-between"
|
| 24 |
+
px={{ base: '30px', md: '50px' }}
|
| 25 |
+
pb="30px"
|
| 26 |
+
>
|
| 27 |
+
<Text
|
| 28 |
+
color={textColor}
|
| 29 |
+
fontSize={{ base: 'xs', md: 'sm' }}
|
| 30 |
+
textAlign={{
|
| 31 |
+
base: 'center',
|
| 32 |
+
xl: 'start',
|
| 33 |
+
}}
|
| 34 |
+
fontWeight="500"
|
| 35 |
+
mb={{ base: '10px', xl: '0px' }}
|
| 36 |
+
>
|
| 37 |
+
{' '}
|
| 38 |
+
© {new Date().getFullYear()}
|
| 39 |
+
<Text as="span" fontWeight="500" ms="4px">
|
| 40 |
+
Horizon UI AI Template. All Rights Reserved.
|
| 41 |
+
</Text>
|
| 42 |
+
</Text>
|
| 43 |
+
<List display="flex">
|
| 44 |
+
<ListItem
|
| 45 |
+
me={{
|
| 46 |
+
base: '10px',
|
| 47 |
+
md: '44px',
|
| 48 |
+
}}
|
| 49 |
+
>
|
| 50 |
+
<Link
|
| 51 |
+
fontWeight="500"
|
| 52 |
+
fontSize={{ base: 'xs', md: 'sm' }}
|
| 53 |
+
color={textColor}
|
| 54 |
+
href="https://horizon-ui.com/pro"
|
| 55 |
+
>
|
| 56 |
+
Homepage
|
| 57 |
+
</Link>
|
| 58 |
+
</ListItem>
|
| 59 |
+
<ListItem
|
| 60 |
+
me={{
|
| 61 |
+
base: '10px',
|
| 62 |
+
md: '44px',
|
| 63 |
+
}}
|
| 64 |
+
>
|
| 65 |
+
<Link
|
| 66 |
+
fontWeight="500"
|
| 67 |
+
fontSize={{ base: 'xs', md: 'sm' }}
|
| 68 |
+
color={textColor}
|
| 69 |
+
href="https://horizon-ui.notion.site/End-User-License-Agreement-8fb09441ea8c4c08b60c37996195a6d5"
|
| 70 |
+
>
|
| 71 |
+
License
|
| 72 |
+
</Link>
|
| 73 |
+
</ListItem>
|
| 74 |
+
<ListItem
|
| 75 |
+
me={{
|
| 76 |
+
base: '10px',
|
| 77 |
+
md: '44px',
|
| 78 |
+
}}
|
| 79 |
+
>
|
| 80 |
+
<Link
|
| 81 |
+
fontWeight="500"
|
| 82 |
+
fontSize={{ base: 'xs', md: 'sm' }}
|
| 83 |
+
color={textColor}
|
| 84 |
+
href="https://horizon-ui.notion.site/Terms-Conditions-6e79229d25ed48f48a481962bc6de3ee"
|
| 85 |
+
>
|
| 86 |
+
Terms of Use
|
| 87 |
+
</Link>
|
| 88 |
+
</ListItem>
|
| 89 |
+
<ListItem>
|
| 90 |
+
<Link
|
| 91 |
+
fontWeight="500"
|
| 92 |
+
fontSize={{ base: 'xs', md: 'sm' }}
|
| 93 |
+
color={textColor}
|
| 94 |
+
href="https://horizon-ui.notion.site/Privacy-Policy-8addde50aa8e408ca5c5f5811c38f971"
|
| 95 |
+
>
|
| 96 |
+
Privacy Policy
|
| 97 |
+
</Link>
|
| 98 |
+
</ListItem>
|
| 99 |
+
</List>
|
| 100 |
+
</Flex>
|
| 101 |
+
);
|
| 102 |
+
}
|
src/components/icons/IconBox.tsx
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
'use client'
|
| 2 |
+
import { Flex } from '@chakra-ui/react';
|
| 3 |
+
|
| 4 |
+
export default function IconBox(props: { icon: JSX.Element | string; [x: string]: any }) {
|
| 5 |
+
const { icon, ...rest } = props;
|
| 6 |
+
|
| 7 |
+
return (
|
| 8 |
+
<Flex
|
| 9 |
+
alignItems={'center'}
|
| 10 |
+
justifyContent={'center'}
|
| 11 |
+
borderRadius={'50%'}
|
| 12 |
+
{...rest}
|
| 13 |
+
>
|
| 14 |
+
{icon}
|
| 15 |
+
</Flex>
|
| 16 |
+
);
|
| 17 |
+
}
|
src/components/icons/Icons.tsx
ADDED
|
@@ -0,0 +1,200 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
'use client';
|
| 2 |
+
import { createIcon } from '@chakra-ui/icons';
|
| 3 |
+
|
| 4 |
+
export const HorizonLogo = createIcon({
|
| 5 |
+
displayName: 'horizonLogo',
|
| 6 |
+
viewBox: '0 0 146 20',
|
| 7 |
+
path: (
|
| 8 |
+
<g fill="currentColor" xmlns="http://www.w3.org/2000/svg">
|
| 9 |
+
<path
|
| 10 |
+
d="M16.42.748V19h-4.446v-7.514H5.058V19H.612V.748h4.446v7.15h6.916V.748h4.446Zm11.842 18.434c-1.716 0-3.294-.399-4.732-1.196a9.092 9.092 0 0 1-3.406-3.328c-.832-1.439-1.248-3.05-1.248-4.836 0-1.785.416-3.389 1.248-4.81a9.092 9.092 0 0 1 3.406-3.328C24.968.887 26.546.488 28.262.488c1.716 0 3.284.399 4.706 1.196a8.665 8.665 0 0 1 3.38 3.328c.832 1.421 1.248 3.025 1.248 4.81 0 1.785-.416 3.397-1.248 4.836a8.901 8.901 0 0 1-3.38 3.328c-1.422.797-2.99 1.196-4.706 1.196Zm0-4.056c1.456 0 2.617-.485 3.484-1.456.884-.97 1.326-2.253 1.326-3.848 0-1.612-.442-2.895-1.326-3.848-.867-.97-2.028-1.456-3.484-1.456-1.474 0-2.652.477-3.536 1.43-.867.953-1.3 2.245-1.3 3.874 0 1.612.433 2.903 1.3 3.874.884.953 2.062 1.43 3.536 1.43ZM49.377 19l-3.796-6.89h-1.066V19h-4.446V.748h7.462c1.439 0 2.66.251 3.666.754 1.023.503 1.785 1.196 2.288 2.08.503.867.754 1.837.754 2.912 0 1.213-.347 2.297-1.04 3.25-.676.953-1.681 1.63-3.016 2.028L54.395 19h-5.018ZM44.515 8.964h2.756c.815 0 1.421-.2 1.82-.598.416-.399.624-.962.624-1.69 0-.693-.208-1.24-.624-1.638-.399-.399-1.005-.598-1.82-.598h-2.756v4.524ZM61.476.748V19H57.03V.748h4.446ZM69.43 15.36h7.852V19H64.386v-3.38l7.8-11.232h-7.8V.748h12.896v3.38L69.43 15.36Zm19.388 3.822c-1.716 0-3.293-.399-4.732-1.196a9.093 9.093 0 0 1-3.406-3.328c-.832-1.439-1.248-3.05-1.248-4.836 0-1.785.416-3.389 1.248-4.81a9.093 9.093 0 0 1 3.406-3.328C85.525.887 87.102.488 88.818.488c1.716 0 3.285.399 4.706 1.196a8.664 8.664 0 0 1 3.38 3.328c.832 1.421 1.248 3.025 1.248 4.81 0 1.785-.416 3.397-1.248 4.836a8.9 8.9 0 0 1-3.38 3.328c-1.421.797-2.99 1.196-4.706 1.196Zm0-4.056c1.456 0 2.618-.485 3.484-1.456.884-.97 1.326-2.253 1.326-3.848 0-1.612-.442-2.895-1.326-3.848-.866-.97-2.028-1.456-3.484-1.456-1.473 0-2.652.477-3.536 1.43-.866.953-1.3 2.245-1.3 3.874 0 1.612.434 2.903 1.3 3.874.884.953 2.063 1.43 3.536 1.43ZM116.954 19h-4.446l-7.436-11.258V19h-4.446V.748h4.446l7.436 11.31V.748h4.446V19Zm19.834-4.03h-7.904L127.428 19h-2.496L131.484.982h2.73L140.74 19h-2.496l-1.456-4.03Zm-.676-1.924-3.276-9.152-3.276 9.152h6.552Zm9.85-12.168V19h-2.366V.878h2.366Z"
|
| 11 |
+
fill="currentColor"
|
| 12 |
+
/>
|
| 13 |
+
</g>
|
| 14 |
+
),
|
| 15 |
+
});
|
| 16 |
+
|
| 17 |
+
export const RoundedChart = createIcon({
|
| 18 |
+
displayName: 'RoundedChart',
|
| 19 |
+
viewBox: '0 0 24 24',
|
| 20 |
+
path: (
|
| 21 |
+
<svg width="24" height="24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
| 22 |
+
<path
|
| 23 |
+
d="M5.846 20c-.515 0-.951-.18-1.31-.539A1.79 1.79 0 0 1 4 18.148v-4.53c0-.515.18-.953.539-1.312.36-.36.796-.54 1.311-.54.515 0 .954.18 1.318.54.364.359.545.797.545 1.312v4.53c0 .516-.182.954-.547 1.313a1.81 1.81 0 0 1-1.32.539ZM12 20c-.515 0-.952-.18-1.311-.539a1.785 1.785 0 0 1-.539-1.31V5.85c0-.515.18-.952.54-1.311A1.78 1.78 0 0 1 12 4c.515 0 .952.18 1.311.539.36.36.539.796.539 1.31V18.15c0 .515-.18.952-.54 1.311A1.78 1.78 0 0 1 12 20Zm6.15 0c-.515 0-.954-.18-1.318-.539a1.78 1.78 0 0 1-.546-1.317V10.71c0-.519.183-.958.548-1.317.365-.36.805-.539 1.32-.539s.951.18 1.31.54c.357.358.536.797.536 1.316v7.434c0 .519-.18.958-.539 1.317-.36.36-.796.539-1.311.539Z"
|
| 24 |
+
fill="currentColor"
|
| 25 |
+
/>
|
| 26 |
+
</svg>
|
| 27 |
+
),
|
| 28 |
+
});
|
| 29 |
+
|
| 30 |
+
export const Logo = createIcon({
|
| 31 |
+
displayName: 'Logo',
|
| 32 |
+
viewBox: '0 0 217 39',
|
| 33 |
+
path: (
|
| 34 |
+
<svg width="217" height="39" fill="none" xmlns="http://www.w3.org/2000/svg">
|
| 35 |
+
<rect
|
| 36 |
+
width="38.969"
|
| 37 |
+
height="38.969"
|
| 38 |
+
rx="8.609"
|
| 39 |
+
fill="url(#Essay Builder Logo__a)"
|
| 40 |
+
/>
|
| 41 |
+
<g filter="url(#Essay Builder Logo__b)">
|
| 42 |
+
<path
|
| 43 |
+
d="M28.74 14.57a.646.646 0 0 1-.915 0L25 11.738a.646.646 0 0 1-.006-.907l.63-.649a1.882 1.882 0 0 1 1.386-.567c.547 0 1.037.199 1.47.595l.933.907c.434.416.627.898.58 1.446a2.168 2.168 0 0 1-.636 1.388l-.617.619Zm-2.079 1.164a.646.646 0 0 1 .004.916L12.92 30.425a.646.646 0 0 1-.457.19H9.646A.646.646 0 0 1 9 29.97v-2.828c0-.17.068-.335.189-.456l13.72-13.752a.646.646 0 0 1 .911-.004l2.841 2.805Z"
|
| 44 |
+
fill="url(#Essay Builder Logo__c)"
|
| 45 |
+
shape-rendering="crispEdges"
|
| 46 |
+
/>
|
| 47 |
+
</g>
|
| 48 |
+
<g filter="url(#Essay Builder Logo__d)">
|
| 49 |
+
<path
|
| 50 |
+
d="M13.613 10.074a.323.323 0 0 0-.583-.001l-1.012 2.109a.324.324 0 0 1-.162.156l-2.174.948a.323.323 0 0 0 .001.593l2.17.937a.32.32 0 0 1 .162.156l1.015 2.112a.323.323 0 0 0 .583-.001l1.004-2.11a.323.323 0 0 1 .164-.157l2.178-.937a.323.323 0 0 0 0-.593l-2.181-.947a.323.323 0 0 1-.164-.158l-1-2.107Zm4.832-1.456a.323.323 0 0 0-.584 0l-.329.695a.323.323 0 0 1-.167.16l-.687.29a.323.323 0 0 0-.004.593l.695.304a.323.323 0 0 1 .162.157l.33.692a.323.323 0 0 0 .583 0l.33-.692a.323.323 0 0 1 .162-.157l.69-.304a.323.323 0 0 0-.005-.593l-.682-.29a.323.323 0 0 1-.165-.16l-.33-.695Z"
|
| 51 |
+
fill="url(#Essay Builder Logo__e)"
|
| 52 |
+
shape-rendering="crispEdges"
|
| 53 |
+
/>
|
| 54 |
+
</g>
|
| 55 |
+
<path
|
| 56 |
+
d="M48.455 27.167v-15.91h10.7v2.882h-7.39v3.61h6.963v2.883h-6.962v3.652h7.389v2.883h-10.7Zm16.485.256c-1.282 0-2.4-.299-3.353-.897-.94-.612-1.58-1.43-1.923-2.456l2.35-1.11c.299.626.704 1.117 1.217 1.473a2.928 2.928 0 0 0 1.708.534c.456 0 .805-.093 1.047-.278.242-.185.363-.441.363-.768a.692.692 0 0 0-.128-.428 1.14 1.14 0 0 0-.385-.341c-.17-.1-.384-.185-.64-.257l-1.986-.555c-.954-.27-1.688-.705-2.2-1.303-.513-.612-.769-1.33-.769-2.156 0-.727.185-1.36.555-1.901.37-.541.89-.961 1.56-1.26.669-.314 1.437-.47 2.306-.47 1.139 0 2.135.27 2.99.811a4.268 4.268 0 0 1 1.836 2.243l-2.37 1.11a2.193 2.193 0 0 0-.94-1.153 2.64 2.64 0 0 0-1.516-.448c-.413 0-.74.085-.983.256a.833.833 0 0 0-.341.705.75.75 0 0 0 .128.427 1.1 1.1 0 0 0 .406.341c.199.1.441.193.726.278l1.858.555c.968.285 1.708.72 2.22 1.303.513.57.77 1.274.77 2.114 0 .726-.192 1.36-.577 1.901-.37.541-.89.968-1.559 1.281-.67.3-1.46.449-2.37.449Zm10.563 0c-1.281 0-2.399-.299-3.353-.897-.94-.612-1.58-1.43-1.922-2.456l2.35-1.11c.298.626.704 1.117 1.217 1.473a2.928 2.928 0 0 0 1.708.534c.456 0 .805-.093 1.047-.278.242-.185.363-.441.363-.768a.691.691 0 0 0-.128-.428 1.14 1.14 0 0 0-.385-.341c-.17-.1-.384-.185-.64-.257l-1.987-.555c-.953-.27-1.687-.705-2.2-1.303-.512-.612-.768-1.33-.768-2.156 0-.727.185-1.36.555-1.901.37-.541.89-.961 1.56-1.26.668-.314 1.437-.47 2.306-.47 1.139 0 2.135.27 2.99.811a4.268 4.268 0 0 1 1.836 2.243l-2.37 1.11a2.193 2.193 0 0 0-.94-1.153 2.64 2.64 0 0 0-1.516-.448c-.413 0-.74.085-.983.256a.833.833 0 0 0-.341.705.75.75 0 0 0 .128.427 1.1 1.1 0 0 0 .406.341c.199.1.44.193.726.278l1.858.555c.968.285 1.708.72 2.22 1.303.513.57.77 1.274.77 2.114 0 .726-.193 1.36-.577 1.901-.37.541-.89.968-1.56 1.281-.668.3-1.458.449-2.37.449Zm9.603 0c-.84 0-1.566-.135-2.178-.406-.612-.27-1.082-.655-1.41-1.153-.327-.513-.49-1.118-.49-1.815 0-.655.149-1.232.448-1.73.299-.513.754-.94 1.366-1.282.627-.341 1.403-.583 2.328-.726l3.567-.576v2.349l-2.99.534c-.456.085-.805.235-1.047.448-.242.2-.363.492-.363.876 0 .356.136.634.406.833.27.2.605.299 1.004.299.527 0 .99-.114 1.388-.342a2.37 2.37 0 0 0 .918-.918 2.58 2.58 0 0 0 .342-1.303v-3.033c0-.44-.178-.811-.534-1.11-.342-.3-.811-.449-1.41-.449-.569 0-1.074.157-1.516.47-.427.314-.74.726-.94 1.239l-2.562-1.217a4.163 4.163 0 0 1 1.09-1.688 5.184 5.184 0 0 1 1.793-1.089 6.578 6.578 0 0 1 2.285-.384c.983 0 1.851.178 2.606.534.754.356 1.338.854 1.75 1.495.428.626.642 1.36.642 2.2v7.688h-2.99v-1.88l.726-.128a5.91 5.91 0 0 1-1.132 1.282 4.18 4.18 0 0 1-1.388.726 5.382 5.382 0 0 1-1.709.256Zm10.23 4.485c-.342 0-.676-.029-1.004-.086a2.867 2.867 0 0 1-.833-.277v-2.627a6.017 6.017 0 0 0 1.453.213c.626 0 1.075-.149 1.345-.448.27-.299.491-.64.662-1.025l.79-1.815-.042 2.67-5.126-13.007h3.438l3.396 9.247h-1.281l3.395-9.247h3.439l-4.998 12.75c-.313.811-.697 1.488-1.153 2.029a4.517 4.517 0 0 1-1.559 1.217c-.57.27-1.21.406-1.922.406Zm11.395-9.183v-2.777h9.61v2.777h-9.61Zm12.553 4.442v-15.91h6.727c1.096 0 2.036.184 2.819.555.783.37 1.381.904 1.794 1.601.413.684.619 1.517.619 2.499a3.85 3.85 0 0 1-.576 2.007c-.385.627-1.018 1.154-1.901 1.58v-1.622c.84.327 1.488.719 1.943 1.174.456.456.769.954.94 1.495.171.527.256 1.082.256 1.666 0 1.566-.519 2.784-1.559 3.652-1.039.868-2.484 1.303-4.335 1.303h-6.727Zm3.31-2.883h3.801c.67 0 1.204-.193 1.602-.577.399-.384.598-.883.598-1.495 0-.626-.199-1.132-.598-1.516-.398-.385-.932-.577-1.602-.577h-3.801v4.165Zm0-7.048h3.652c.513 0 .918-.142 1.217-.427.313-.3.47-.69.47-1.175 0-.484-.157-.868-.47-1.153-.299-.299-.704-.448-1.217-.448h-3.652v3.203Zm14.959 10.187c-.94 0-1.745-.2-2.414-.598a3.971 3.971 0 0 1-1.495-1.709c-.341-.726-.512-1.573-.512-2.54v-7.07h3.203v6.813c0 .441.086.833.257 1.174a2 2 0 0 0 .768.77 2.22 2.22 0 0 0 1.111.277c.427 0 .797-.093 1.11-.278a1.85 1.85 0 0 0 .748-.769c.185-.341.278-.733.278-1.174v-6.813h3.203v11.66h-2.99V24.86l.171.513c-.271.697-.712 1.217-1.324 1.559-.598.327-1.303.491-2.114.491Zm8.171-.256v-11.66h3.204v11.66h-3.204Zm0-12.707v-3.204h3.204v3.204h-3.204Zm5.121 12.707V11h3.203v16.167h-3.203Zm10.609.256c-1.139 0-2.157-.27-3.054-.812a5.976 5.976 0 0 1-2.136-2.2c-.512-.925-.769-1.95-.769-3.075 0-1.139.264-2.164.791-3.075a5.967 5.967 0 0 1 2.135-2.2c.897-.54 1.901-.811 3.011-.811.855 0 1.609.164 2.264.491a3.746 3.746 0 0 1 1.58 1.346l-.491.64V11h3.204v16.167h-2.99V25.03l.299.662c-.399.57-.94 1.004-1.623 1.303a5.719 5.719 0 0 1-2.221.427Zm.384-2.883c.584 0 1.096-.135 1.538-.406.441-.27.783-.648 1.025-1.132.256-.484.384-1.04.384-1.666 0-.626-.128-1.181-.384-1.665a2.727 2.727 0 0 0-1.025-1.132c-.442-.27-.954-.406-1.538-.406-.584 0-1.11.142-1.58.427-.456.27-.812.648-1.068 1.132-.256.47-.384 1.018-.384 1.644 0 .627.128 1.182.384 1.666s.612.862 1.068 1.132c.47.27.996.406 1.58.406Zm13.686 2.883c-1.238 0-2.313-.27-3.224-.812a5.76 5.76 0 0 1-2.115-2.22c-.498-.926-.747-1.951-.747-3.076 0-1.167.256-2.207.769-3.118a5.9 5.9 0 0 1 2.114-2.157c.883-.527 1.879-.79 2.99-.79.925 0 1.744.15 2.456.448.712.285 1.31.69 1.794 1.218a5.318 5.318 0 0 1 1.132 1.836 6.345 6.345 0 0 1 .341 2.926c-.014.214-.05.399-.107.555h-8.734v-2.349h6.919l-1.516 1.11c.142-.611.135-1.152-.021-1.622a2.113 2.113 0 0 0-.833-1.132c-.385-.285-.862-.427-1.431-.427-.555 0-1.032.135-1.431.405s-.698.67-.897 1.196c-.199.527-.278 1.168-.235 1.922-.057.655.021 1.232.235 1.73.213.499.541.89.982 1.175.442.27.976.406 1.602.406.57 0 1.054-.114 1.452-.342.413-.228.733-.541.961-.94l2.563 1.218a3.83 3.83 0 0 1-1.089 1.495 5.318 5.318 0 0 1-1.73 1.003 6.786 6.786 0 0 1-2.2.342Zm7.012-.256v-11.66h2.99v2.797l-.214-.406c.257-.982.677-1.644 1.26-1.986.598-.356 1.303-.534 2.115-.534h.683v2.776h-1.004c-.783 0-1.416.242-1.9.727-.484.47-.726 1.139-.726 2.007v6.279h-3.204Zm8.536 0v-3.204h3.204v3.204h-3.204Zm5.771 0 5.382-15.91h4.399l5.382 15.91h-3.609l-1.068-3.247h-5.83l-1.068 3.247h-3.588Zm5.574-6.13h3.993l-2.434-7.517h.897l-2.456 7.517Zm10.815 6.13v-15.91h3.31v15.91h-3.31Z"
|
| 57 |
+
fill="#120F43"
|
| 58 |
+
/>
|
| 59 |
+
<defs>
|
| 60 |
+
<linearGradient
|
| 61 |
+
id="Essay Builder Logo__a"
|
| 62 |
+
x1="23.267"
|
| 63 |
+
y1="32.321"
|
| 64 |
+
x2="31.554"
|
| 65 |
+
y2="2.363"
|
| 66 |
+
gradientUnits="userSpaceOnUse"
|
| 67 |
+
>
|
| 68 |
+
<stop stop-color="#4A25E1" />
|
| 69 |
+
<stop offset="1" stop-color="#9C84FF" />
|
| 70 |
+
</linearGradient>
|
| 71 |
+
<linearGradient
|
| 72 |
+
id="Essay Builder Logo__c"
|
| 73 |
+
x1="23.171"
|
| 74 |
+
y1="19.5"
|
| 75 |
+
x2="20.095"
|
| 76 |
+
y2="34.225"
|
| 77 |
+
gradientUnits="userSpaceOnUse"
|
| 78 |
+
>
|
| 79 |
+
<stop stop-color="#fff" stop-opacity=".96" />
|
| 80 |
+
<stop offset="1" stop-color="#fff" stop-opacity=".23" />
|
| 81 |
+
</linearGradient>
|
| 82 |
+
<linearGradient
|
| 83 |
+
id="Essay Builder Logo__e"
|
| 84 |
+
x1="16.631"
|
| 85 |
+
y1="13.13"
|
| 86 |
+
x2="15.4"
|
| 87 |
+
y2="6.258"
|
| 88 |
+
gradientUnits="userSpaceOnUse"
|
| 89 |
+
>
|
| 90 |
+
<stop stop-color="#fff" stop-opacity=".96" />
|
| 91 |
+
<stop offset="1" stop-color="#fff" stop-opacity=".23" />
|
| 92 |
+
</linearGradient>
|
| 93 |
+
<filter
|
| 94 |
+
id="Essay Builder Logo__b"
|
| 95 |
+
x="4.071"
|
| 96 |
+
y="5.309"
|
| 97 |
+
width="30.292"
|
| 98 |
+
height="31.142"
|
| 99 |
+
filterUnits="userSpaceOnUse"
|
| 100 |
+
color-interpolation-filters="sRGB"
|
| 101 |
+
>
|
| 102 |
+
<feFlood flood-opacity="0" result="BackgroundImageFix" />
|
| 103 |
+
<feColorMatrix
|
| 104 |
+
in="SourceAlpha"
|
| 105 |
+
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
|
| 106 |
+
result="hardAlpha"
|
| 107 |
+
/>
|
| 108 |
+
<feOffset dx="-1.02" dy="1.926" />
|
| 109 |
+
<feGaussianBlur stdDeviation="1.955" />
|
| 110 |
+
<feComposite in2="hardAlpha" operator="out" />
|
| 111 |
+
<feColorMatrix values="0 0 0 0 0.0506089 0 0 0 0 0.0159861 0 0 0 0 0.191833 0 0 0 0.25 0" />
|
| 112 |
+
<feBlend
|
| 113 |
+
in2="BackgroundImageFix"
|
| 114 |
+
result="effect1_dropShadow_1_6125"
|
| 115 |
+
/>
|
| 116 |
+
<feColorMatrix
|
| 117 |
+
in="SourceAlpha"
|
| 118 |
+
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
|
| 119 |
+
result="hardAlpha"
|
| 120 |
+
/>
|
| 121 |
+
<feOffset dx=".963" dy="-.907" />
|
| 122 |
+
<feGaussianBlur stdDeviation="1.7" />
|
| 123 |
+
<feComposite in2="hardAlpha" operator="out" />
|
| 124 |
+
<feColorMatrix values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.35 0" />
|
| 125 |
+
<feBlend
|
| 126 |
+
in2="effect1_dropShadow_1_6125"
|
| 127 |
+
result="effect2_dropShadow_1_6125"
|
| 128 |
+
/>
|
| 129 |
+
<feBlend
|
| 130 |
+
in="SourceGraphic"
|
| 131 |
+
in2="effect2_dropShadow_1_6125"
|
| 132 |
+
result="shape"
|
| 133 |
+
/>
|
| 134 |
+
<feColorMatrix
|
| 135 |
+
in="SourceAlpha"
|
| 136 |
+
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
|
| 137 |
+
result="hardAlpha"
|
| 138 |
+
/>
|
| 139 |
+
<feOffset dy="2.38" />
|
| 140 |
+
<feGaussianBlur stdDeviation="1.501" />
|
| 141 |
+
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1" />
|
| 142 |
+
<feColorMatrix values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0" />
|
| 143 |
+
<feBlend in2="shape" result="effect3_innerShadow_1_6125" />
|
| 144 |
+
</filter>
|
| 145 |
+
<filter
|
| 146 |
+
id="Essay Builder Logo__d"
|
| 147 |
+
x="4.559"
|
| 148 |
+
y="4.127"
|
| 149 |
+
width="19.622"
|
| 150 |
+
height="18.976"
|
| 151 |
+
filterUnits="userSpaceOnUse"
|
| 152 |
+
color-interpolation-filters="sRGB"
|
| 153 |
+
>
|
| 154 |
+
<feFlood flood-opacity="0" result="BackgroundImageFix" />
|
| 155 |
+
<feColorMatrix
|
| 156 |
+
in="SourceAlpha"
|
| 157 |
+
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
|
| 158 |
+
result="hardAlpha"
|
| 159 |
+
/>
|
| 160 |
+
<feOffset dx="-1.02" dy="1.926" />
|
| 161 |
+
<feGaussianBlur stdDeviation="1.955" />
|
| 162 |
+
<feComposite in2="hardAlpha" operator="out" />
|
| 163 |
+
<feColorMatrix values="0 0 0 0 0.0506089 0 0 0 0 0.0159861 0 0 0 0 0.191833 0 0 0 0.25 0" />
|
| 164 |
+
<feBlend
|
| 165 |
+
in2="BackgroundImageFix"
|
| 166 |
+
result="effect1_dropShadow_1_6125"
|
| 167 |
+
/>
|
| 168 |
+
<feColorMatrix
|
| 169 |
+
in="SourceAlpha"
|
| 170 |
+
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
|
| 171 |
+
result="hardAlpha"
|
| 172 |
+
/>
|
| 173 |
+
<feOffset dx=".963" dy="-.907" />
|
| 174 |
+
<feGaussianBlur stdDeviation="1.7" />
|
| 175 |
+
<feComposite in2="hardAlpha" operator="out" />
|
| 176 |
+
<feColorMatrix values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.35 0" />
|
| 177 |
+
<feBlend
|
| 178 |
+
in2="effect1_dropShadow_1_6125"
|
| 179 |
+
result="effect2_dropShadow_1_6125"
|
| 180 |
+
/>
|
| 181 |
+
<feBlend
|
| 182 |
+
in="SourceGraphic"
|
| 183 |
+
in2="effect2_dropShadow_1_6125"
|
| 184 |
+
result="shape"
|
| 185 |
+
/>
|
| 186 |
+
<feColorMatrix
|
| 187 |
+
in="SourceAlpha"
|
| 188 |
+
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
|
| 189 |
+
result="hardAlpha"
|
| 190 |
+
/>
|
| 191 |
+
<feOffset dy="2.38" />
|
| 192 |
+
<feGaussianBlur stdDeviation="1.501" />
|
| 193 |
+
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1" />
|
| 194 |
+
<feColorMatrix values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0" />
|
| 195 |
+
<feBlend in2="shape" result="effect3_innerShadow_1_6125" />
|
| 196 |
+
</filter>
|
| 197 |
+
</defs>
|
| 198 |
+
</svg>
|
| 199 |
+
),
|
| 200 |
+
});
|