Functional AI Page

This commit is contained in:
Luke Hagar
2023-07-25 07:55:07 -05:00
parent 1cc840a618
commit 328a2f9344
11 changed files with 1375 additions and 9 deletions

1078
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -24,7 +24,14 @@
"@docusaurus/plugin-client-redirects": "2.2.0",
"@docusaurus/plugin-google-tag-manager": "^2.4.1",
"@docusaurus/theme-mermaid": "2.2.0",
"@emotion/react": "^11.11.1",
"@mantine/core": "^6.0.17",
"@mantine/dropzone": "^6.0.17",
"@mantine/form": "^6.0.17",
"@mantine/hooks": "^6.0.17",
"@mantine/prism": "^6.0.17",
"@mdx-js/react": "^1.6.22",
"@tabler/icons-react": "^2.29.0",
"@typeform/embed-react": "^1.21.0",
"autoprefixer": "^10.4.13",
"classnames": "^2.3.2",

View File

@@ -0,0 +1,90 @@
import {ActionIcon, Textarea, Text, Transition} from '@mantine/core';
import {IconSend, IconX} from '@tabler/icons-react';
import React, {useRef, useState} from 'react';
import styles from './styles.module.css';
import ResponseCard from '../ResponseCard';
export default function Content() {
const [inputText, setInputText] = useState('');
const [textareaheight, setTextAreaHeight] = useState(1);
const [apiResponse, setApiResponse] = useState([]);
const textBoxRef = useRef(null);
const [loading, setLoading] = useState(true);
setTimeout(() => {
setLoading(false);
}, 400);
const reset = async () => {
setApiResponse([]);
};
const submitQuery = async (e) => {
if (e.keyCode === 13 || e.type === 'click') {
// const resp = await fetch('http://127.0.0.1:5000/chatbot', {
// method: 'POST',
// body: {query: textBoxRef.current.value},
// });
// console.log(resp);
setApiResponse([
...apiResponse,
{
answer:
'The best way to access the SailPoint APIs is either by using the client credentials OAuth2 flow or a personal access token. The client credentials flow is recommended for authentication with client-side scripts or programs. If you need to access endpoints that require a user context, such as the /v3/access-requests endpoint, you will need to generate an access token using your personal access token credentials. For more information, you can refer to the API docs on the SailPoint developer portal.',
chat_history: [
[
'What is the best way to access the SailPoint APIs',
'The best way to access the SailPoint APIs is either by using the client credentials OAuth2 flow or a personal access token. The client credentials flow is recommended for authentication with client-side scripts or programs. If you need to access endpoints that require a user context, such as the /v3/access-requests endpoint, you will need to generate an access token using your personal access token credentials. For more information, you can refer to the API docs on the SailPoint developer portal.',
],
],
question: 'What is the best way to access the SailPoint APIs',
},
]);
}
};
return (
<>
<div className={styles.outterContainer}>
<div className={styles.innerContainer}>
<div style={{display: 'flex', flexDirection: 'row'}}>
<Textarea
style={{fontFamily: 'poppins', flexGrow: 1, marginRight: '10px'}}
ref={textBoxRef}
variant="filled"
label="Prompt"
placeholder="Input a query..."
autosize
minRows={2}
maxRows={30}
/>
<div style={{display: 'flex', flexDirection: 'column', gap: '2px'}}>
<ActionIcon
onClick={reset}
color="blue"
size="xl"
variant="filled"
loading={loading}>
<IconX size="1rem" />
</ActionIcon>
<ActionIcon
onClick={submitQuery}
color="blue"
size="xl"
variant="filled"
loading={loading}>
<IconSend size="1rem" />
</ActionIcon>
</div>
</div>
</div>
</div>
<div className={styles.outterContainer} style={{overflow: 'auto'}}>
<div className={styles.innerContainer}>
{apiResponse.length > 0 &&
apiResponse.map((item) => <ResponseCard Item={item} />)}
</div>
</div>
</>
);
}

View File

@@ -0,0 +1,48 @@
.textArea {
font-family: poppins;
padding: 5px;
padding-right: 20px;
width: 100%;
border: 0 solid #ccc;
border-radius: 4px;
min-height: 40px;
max-height: 300px;
resize: none;
}
.buttonContainer {
place-content: center;
position: absolute;
display: flex;
flex-direction: row;
gap: 5px;
}
.submitButton {
height: 40px;
}
.resetButton {
height: 40px;
}
.inputContainer {
postition: relative;
}
.outterContainer {
display: flex;
flex-direction: row;
justify-content: center;
}
.innerContainer {
display: flex;
flex-direction: column;
gap: 10px;
justify-content: center;
padding-top: 20px;
padding-left: 20px;
padding-right: 20px;
width: 98vw;
}

View File

@@ -0,0 +1,19 @@
import React from 'react';
import clsx from 'clsx';
import styles from './styles.module.css';
import useBaseUrl from '@docusaurus/useBaseUrl';
import Link from '@docusaurus/Link';
export default function Header() {
return (
<div>
<div className={styles.imageContainer}>
<img
className={styles.headerImage}
src={useBaseUrl('/blog/blog_banner_template.png')}
/>
<div className={styles.headerText}> Services AI </div>
</div>
</div>
);
}

View File

@@ -0,0 +1,31 @@
.headerText {
position: relative;
color: #ffffff;
font-size: 48px;
max-width: 396px;
font-weight: bold;
line-height: 133%;
top: -84px;
left: 59px;
}
.background {
width: 100%;
object-fit: repeat;
height: 100%;
}
.imageContainer {
width: 100%;
height: 90px;
background: rgb(0, 51, 161);
background: linear-gradient(
90deg,
rgba(0, 51, 161, 1) 0%,
rgba(84, 192, 232, 1) 100%
);
}
.headerImage {
height: 90px;
}

View File

@@ -0,0 +1,31 @@
import {ActionIcon, Card, Textarea, Text, Transition} from '@mantine/core';
import {IconSend, IconX} from '@tabler/icons-react';
import React, {useRef, useState} from 'react';
import styles from './styles.module.css';
export default function ResponseCard({Item}) {
const [mounted, setMounted] = useState(false);
setTimeout(() => {
setMounted(true);
}, 10);
return (
<Transition
mounted={mounted}
transition="slide-down"
duration={400}
timingFunction="ease">
{(styles) => (
<div style={styles}>
<Card shadow="sm" padding="md" radius="md" withBorder>
<Text size="lg">{Item.question}</Text>
<Text size="md" color="dimmed">
{Item.answer}
</Text>
</Card>
</div>
)}
</Transition>
);
}

View File

@@ -0,0 +1,46 @@
.textArea {
font-family: poppins;
padding: 5px;
padding-right: 20px;
width: 100%;
border: 0 solid #ccc;
border-radius: 4px;
min-height: 40px;
max-height: 300px;
resize: none;
}
.buttonContainer {
place-content: center;
position: absolute;
display: flex;
flex-direction: row;
gap: 5px;
}
.submitButton {
height: 40px;
}
.resetButton {
height: 40px;
}
.inputContainer {
postition: relative;
}
.outterContainer {
display: flex;
flex-direction: row;
justify-content: center;
}
.innerContainer {
display: flex;
flex-direction: column;
gap: 10px;
justify-content: center;
padding: 20px;
width: 98vw;
}

20
src/pages/ai.js Normal file
View File

@@ -0,0 +1,20 @@
import React from 'react';
import clsx from 'clsx';
import Link from '@docusaurus/Link';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
import Layout from '@theme/Layout';
import Header from '../components/ServicesAI/Header';
import Content from '../components/ServicesAI/Content';
export default function AI() {
const {siteConfig} = useDocusaurusContext();
return (
<Layout description="The SailPoint Developer Community has everything you need to build, extend, and automate scalable identity solutions.">
<main>
<Header />
<Content />
</main>
</Layout>
);
}

0
src/pages/ai.module.css Normal file
View File

14
static/icons/send.svg Normal file
View File

@@ -0,0 +1,14 @@
<svg fill="#000000" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 512 512" xml:space="preserve">
<g>
<g>
<g>
<path d="M0,234.919l174.682,102.399l102.399,174.682L512,0.001L0,234.919z M275.387,478.16l-85.176-145.304l52.097-52.097
l-11.068-11.068l-52.098,52.098L33.84,236.612L459.726,41.206L293.249,207.681l11.068,11.068L470.795,52.275L275.387,478.16z"/>
<rect x="257.132" y="223.121" transform="matrix(-0.7071 -0.7071 0.7071 -0.7071 277.6292 609.0733)" width="15.652" height="47.834"/>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 600 B