diff --git a/components/lexy/Claim.js b/components/lexy/Claim.js new file mode 100644 index 00000000..a1a55340 --- /dev/null +++ b/components/lexy/Claim.js @@ -0,0 +1,34 @@ +import React from 'react' +import { useAccount, useContractWrite } from 'wagmi' +import { Button } from '../../styles/elements' + +// create a react component called Claim that renders a button that when clicked calls the claim function +export default function Claim() { + const { data: account } = useAccount() + const { isLoading: isClaimPending, writeAsync } = useContractWrite( + { + addressOrName: '', + contractInterface: '', + }, + 'claim', + ) + + const claim = async () => { + // claim function calls the claim function in the KaliToken contract on polygon using wagmi's useContractWrite hook + if (!account) return + } + return ( + + ) +} diff --git a/components/lexy/Counter.js b/components/lexy/Counter.js new file mode 100644 index 00000000..85b4affb --- /dev/null +++ b/components/lexy/Counter.js @@ -0,0 +1,33 @@ +import React from 'react' +import Claim from './Claim' +import { useAccount } from 'wagmi' +import { Flex, Box, Button } from '../../styles/elements' + +// a counter component that receieve a count prop +export default function Counter({ count }) { + const { data: account } = useAccount() + const claim = async () => { + if (!account) return + } + + return ( + + {count} KALI + + + ) +} diff --git a/components/lexy/Send.js b/components/lexy/Send.js new file mode 100644 index 00000000..3a3e3cac --- /dev/null +++ b/components/lexy/Send.js @@ -0,0 +1,41 @@ +import React from 'react' +import { styled } from '../../styles/stitches.config' +import { Flex, Text, Button } from '../../styles/elements' +import { Form, Input } from '../../styles/form-elements' +import { PaperPlaneIcon } from '@radix-ui/react-icons' + +const Icon = styled(PaperPlaneIcon, { + transform: 'rotate(330deg)', +}) + +export default function Send({ loading, submit, question, setQuestion }) { + return ( +
+ setQuestion(e.target.value)} + css={{ + fontFamily: 'Regular', + borderRadius: '10px', + }} + /> + +
+ ) +} diff --git a/components/lexy/Text.js b/components/lexy/Text.js new file mode 100644 index 00000000..e1cb4ed8 --- /dev/null +++ b/components/lexy/Text.js @@ -0,0 +1,36 @@ +import React from 'react' +import { Text as TextBox, Flex } from '../../styles/elements' +import { Avatar, AvatarImage, AvatarFallback } from '../../styles/Avatar' +import { getRandomEmoji } from '../../utils' +import { AddressZero } from '@ethersproject/constants' + +export default function Text({ text }) { + return ( + + + + {getRandomEmoji(AddressZero)} + + {text && + text?.text.split('/n').map((line, index) => ( + + {line} + + ))} + + ) +} diff --git a/components/lexy/Texts.js b/components/lexy/Texts.js new file mode 100644 index 00000000..b50a06ce --- /dev/null +++ b/components/lexy/Texts.js @@ -0,0 +1,19 @@ +import React from 'react' +import { Flex } from '../../styles/elements' +import Text from './Text' + +export default function Texts({ texts }) { + console.log('texts', texts) + return ( + + {texts.map((text, index) => ( + + ))} + + ) +} diff --git a/components/lexy/Vote.js b/components/lexy/Vote.js new file mode 100644 index 00000000..b398db2a --- /dev/null +++ b/components/lexy/Vote.js @@ -0,0 +1,14 @@ +import React from 'react' +import { TiThumbsDown, TiThumbsUp } from 'react-icons/ti' +import { Flex } from '../../styles/elements' + +// create a new component that is passed down vote props for voting with thumbs up or thumbs down and update vote to true or false accordingly +export default function Vote({ text }) { + const vote = (bool) => {} + return ( + + + + + ) +} diff --git a/components/lexy/index.js b/components/lexy/index.js new file mode 100644 index 00000000..94b08e7e --- /dev/null +++ b/components/lexy/index.js @@ -0,0 +1,78 @@ +import { useState } from 'react' +import Send from './Send' +import Texts from './Texts' +import Counter from './Counter' +import { Flex } from '../../styles/elements' + +export default function Lexy() { + const [texts, setTexts] = useState([ + { + name: 'Lexy', + text: 'Hey! I am Lexy. I am a legal consulting chatbot. How can I help you?', + }, + ]) + const [question, setQuestion] = useState() + const [count, setCount] = useState(0) + const [loading, setLoading] = useState(false) + + async function submit(e) { + e.preventDefault() + setLoading(true) + let textsArray = texts + let questionObj = {} + questionObj['name'] = 'Human' + questionObj['text'] = question + texts.push(questionObj) + + const response = await fetch('/api/lexy', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ question: `${question} ->` }), + }) + const data = await response.json() + + console.log('data', data?.result) + let answerObj = {} + answerObj['name'] = 'Lexy' + answerObj['text'] = data.result + + textsArray.push(answerObj) + + setTexts(textsArray) + setQuestion('') + setCount(count++) + setLoading(false) + } + + return ( + + + + + + + + ) +} diff --git a/components/my-daos/DaoCard.js b/components/my-daos/DaoCard.js index 12eba7f3..534c61d0 100644 --- a/components/my-daos/DaoCard.js +++ b/components/my-daos/DaoCard.js @@ -5,7 +5,6 @@ import { Flex, Box } from '../../styles/elements' import { getDaoChain } from '../../utils' import { useNetwork } from 'wagmi' import { getRandomEmoji } from '../../utils/' -import { Avatar, AvatarImage, AvatarFallback } from '@radix-ui/react-avatar' const Name = styled('div', { fontFamily: 'Bold', diff --git a/next.config.js b/next.config.js index fc826606..a4fee172 100644 --- a/next.config.js +++ b/next.config.js @@ -6,6 +6,7 @@ module.exports = { webpack: function (config, options) { config.experiments = { topLevelAwait: true, + layers: true, } return config }, diff --git a/package.json b/package.json index 4ba16f37..01c4b64b 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ "moralis": "^1.8.0", "next": "12.1.0", "node": "^17.4.0", + "openai": "^3.0.0", "react": "17.0.2", "react-dom": "17.0.2", "react-hook-form": "^7.30.0", diff --git a/pages/api/lexy.js b/pages/api/lexy.js new file mode 100644 index 00000000..7d751306 --- /dev/null +++ b/pages/api/lexy.js @@ -0,0 +1,22 @@ +import { Configuration, OpenAIApi } from 'openai' + +const configuration = new Configuration({ + apiKey: process.env.OPENAI_API_KEY, +}) +const openai = new OpenAIApi(configuration) + +export default async function (req, res) { + const completion = await openai.createCompletion({ + model: 'davinci:ft-kali-2022-06-20-00-41-12', + prompt: generatePrompt(req.body.question), + temperature: 0.1, + max_tokens: 2000, // max tokens to return + stop: [' END', ' ->'], // stop token + }) + + res.status(200).json({ result: completion.data.choices[0].text }) +} + +function generatePrompt(question) { + return `A conversation with a female lawyer chatbot named Lexy. She is intelligent, helpful and friendly. Who is your favourite Supreme Court judge? -> None of them END. ${question}` +} diff --git a/pages/lexy.js b/pages/lexy.js new file mode 100644 index 00000000..16388f0b --- /dev/null +++ b/pages/lexy.js @@ -0,0 +1,13 @@ +import React from 'react' +import Layout from '../components/layout' +import Lexy from '../components/lexy/index' +import NewDaoSquare from '../components/my-daos/NewDaoSquare' + +export default function LexyPage() { + return ( + + + + + ) +} diff --git a/public/img/lexy.jpeg b/public/img/lexy.jpeg new file mode 100644 index 00000000..d90f1082 Binary files /dev/null and b/public/img/lexy.jpeg differ diff --git a/public/img/preview.png b/public/img/preview.png new file mode 100644 index 00000000..d6de90f2 Binary files /dev/null and b/public/img/preview.png differ diff --git a/styles/form-elements/Input.js b/styles/form-elements/Input.js index fb486484..4fd6f2aa 100644 --- a/styles/form-elements/Input.js +++ b/styles/form-elements/Input.js @@ -91,6 +91,9 @@ const Input = styled('input', { }, }, textarea: { + display: 'flex', + alignItems: 'flex-start', + justifyContent: 'flex-start', padding: '0.5rem', width: '97%', minHeight: '10vh', diff --git a/yarn.lock b/yarn.lock index 5deb0c83..bce7a1aa 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2821,7 +2821,7 @@ axe-core@^4.3.5: resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.4.2.tgz#dcf7fb6dea866166c3eab33d68208afe4d5f670c" integrity sha512-LVAaGp/wkkgYJcjmHsoKx4juT1aQvJyPcW09MLCjVTh3V2cc6PnyempiLMNH5iMdfIX/zdbjUx2KDjMLCTdPeA== -axios@0.26.1: +axios@0.26.1, axios@^0.26.0: version "0.26.1" resolved "https://registry.yarnpkg.com/axios/-/axios-0.26.1.tgz#1ede41c51fcf51bbbd6fd43669caaa4f0495aaa9" integrity sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA== @@ -4587,6 +4587,15 @@ form-data@^3.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" +form-data@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" + integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + form-data@~2.3.2: version "2.3.3" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" @@ -6123,6 +6132,14 @@ once@^1.3.0, once@^1.3.1, once@^1.4.0: dependencies: wrappy "1" +openai@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/openai/-/openai-3.0.0.tgz#0816f1d72ee37820c9ff14d93d597431489fec37" + integrity sha512-YNAPZKzBfE6MnR5Ro/z3uKbg7T3F3W1FoTCtYheKRdEjZeheMX49QYFeL990gBFAhuGziEZCUdhnNT+eIrxX/Q== + dependencies: + axios "^0.26.0" + form-data "^4.0.0" + optionator@^0.9.1: version "0.9.1" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499"