Skip to content

Commit 5414dba

Browse files
Daniel PhiriDaniel Phiri
authored andcommitted
should have committed way earlier
0 parents  commit 5414dba

File tree

29 files changed

+499
-0
lines changed

29 files changed

+499
-0
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Strapi plugin ai-text-gneration
2+
3+
A quick description of ai-text-gneration.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import React from 'react';
2+
import styled from 'styled-components';
3+
import { Icon } from '@strapi/design-system/Icon';
4+
import { Flex } from '@strapi/design-system/Flex';
5+
import Alien from '@strapi/icons/Alien';
6+
7+
const IconBox = styled(Flex)`
8+
/* Hard code color values */
9+
/* to stay consistent between themes */
10+
background-color: #f0f0ff; /* primary100 */
11+
border: 1px solid #d9d8ff; /* primary200 */
12+
svg > path {
13+
fill: #4945ff; /* primary600 */
14+
}
15+
`;
16+
17+
const MyIcon = () => {
18+
return (
19+
<IconBox justifyContent="center" alignItems="center" width={7} height={6} hasRadius aria-hidden>
20+
<Icon as={Alien} />
21+
</IconBox>
22+
);
23+
};
24+
25+
export default AITextIcon;
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/**
2+
*
3+
* Initializer
4+
*
5+
*/
6+
7+
import { useEffect, useRef } from 'react';
8+
import PropTypes from 'prop-types';
9+
import pluginId from '../../pluginId';
10+
11+
const Initializer = ({ setPlugin }) => {
12+
const ref = useRef();
13+
ref.current = setPlugin;
14+
15+
useEffect(() => {
16+
ref.current(pluginId);
17+
}, []);
18+
19+
return null;
20+
};
21+
22+
Initializer.propTypes = {
23+
setPlugin: PropTypes.func.isRequired,
24+
};
25+
26+
export default Initializer;
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
import React, { useState } from 'react';
2+
import { useIntl } from 'react-intl';
3+
import { TextInput } from '@strapi/design-system/TextInput';
4+
import { Stack } from '@strapi/design-system/Stack';
5+
import { Box } from '@strapi/design-system/Box';
6+
import { Button } from '@strapi/design-system/Button';
7+
import { Textarea } from '@strapi/design-system';
8+
import { TwoColsLayout } from '@strapi/design-system';
9+
10+
11+
export default function Index({
12+
name,
13+
error,
14+
description,
15+
onChange,
16+
value,
17+
intlLabel,
18+
attribute,
19+
}) {
20+
const { formatMessage } = useIntl();
21+
const [content, setContent] = useState('');
22+
const [prompt, setPrompt] = useState('');
23+
const [err, setErr] = useState('');
24+
const xet = process.env.OPEN_AI_ACCESS_TOKEN
25+
26+
27+
const aiClick = async () => {
28+
console.log('vars: ', xet)
29+
try {
30+
const response = await fetch('https://api.openai.com/v1/completions', {
31+
method: 'POST',
32+
headers: {
33+
'Content-Type': 'application/json',
34+
'Authorization': `Bearer ${accessToken}` //functionality to be added
35+
},
36+
body: JSON.stringify({
37+
'model': 'text-davinci-001',
38+
'prompt': `${prompt}`,
39+
'temperature': 0.4,
40+
'max_tokens': 64,
41+
'top_p': 1,
42+
'frequency_penalty': 0,
43+
'presence_penalty': 0
44+
})
45+
});
46+
47+
if (!response.ok) {
48+
throw new Error(`Error! status: ${response.status}`);
49+
}
50+
51+
const result = await response.json();
52+
onChange({ target: { name, value: result.choices[0].text, type: attribute.type } })
53+
} catch (err) {
54+
setErr(err.message);
55+
}
56+
}
57+
58+
const clearGeneratedText = async () => {
59+
onChange({ target: { name, value: '', type: attribute.type } })
60+
61+
}
62+
63+
return (
64+
<Box>
65+
<Stack spacing={1}>
66+
<Stack spacing={1}>
67+
<TextInput
68+
placeholder="Please write a prompt for content to generate"
69+
label="Prompt" name="Prompt"
70+
onChange={e => setPrompt(e.target.value)} value={prompt} />
71+
</Stack>
72+
<Box as="p" padding={4}>
73+
<Textarea
74+
placeholder="Generated text"
75+
label="Content"
76+
name="content"
77+
onChange={e => onChange({ target: { name, value: e.target.value, type: attribute.type } })}>
78+
{value}
79+
</Textarea>
80+
</Box>
81+
</Stack>
82+
<Box padding={4}>
83+
<TwoColsLayout
84+
startCol={<Button onClick={aiClick}>Generate</Button>}
85+
endCol={<Button onClick={() => clearGeneratedText()}>Clear</Button>
86+
}
87+
/>
88+
</Box>
89+
</Box>
90+
)
91+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/**
2+
*
3+
* PluginIcon
4+
*
5+
*/
6+
7+
import React from 'react';
8+
import Puzzle from '@strapi/icons/Puzzle';
9+
10+
const PluginIcon = () => <Puzzle />;
11+
12+
export default PluginIcon;

admin/src/index.js

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
import { prefixPluginTranslations } from '@strapi/helper-plugin';
2+
import pluginPkg from '../../package.json';
3+
import pluginId from './pluginId';
4+
import Initializer from './components/Initializer';
5+
import PluginIcon from './components/PluginIcon';
6+
import AITextIcon from './components/PluginIcon';
7+
8+
9+
const name = pluginPkg.strapi.name;
10+
11+
export default {
12+
register(app) {
13+
// app.addMenuLink({
14+
// to: `/plugins/${pluginId}`,
15+
// icon: PluginIcon,
16+
// intlLabel: {
17+
// id: `${pluginId}.plugin.name`,
18+
// defaultMessage: name,
19+
// },
20+
// Component: async () => {
21+
// const component = await import(/* webpackChunkName: "[request]" */ './pages/App');
22+
23+
// return component;
24+
// },
25+
// permissions: [
26+
// // Uncomment to set the permissions of the plugin here
27+
// // {
28+
// // action: '', // the action name should be plugin::plugin-name.actionType
29+
// // subject: null,
30+
// // },
31+
// ],
32+
// });
33+
// app.registerPlugin({
34+
// id: pluginId,
35+
// initializer: Initializer,
36+
// isReady: false,
37+
// name,
38+
// });
39+
app.customFields.register({
40+
name: "text-ai",
41+
pluginId: "ai-text-generation", // the custom field is created by a color-picker plugin
42+
type: "string", // the color will be stored as a string
43+
intlLabel: {
44+
id: "ai-text-generation.text-ai.label",
45+
defaultMessage: "Text AI",
46+
},
47+
intlDescription: {
48+
id: "ai-text-generation.text-ai.description",
49+
defaultMessage: "Let AI do your writing!",
50+
},
51+
icon: AITextIcon, // don't forget to create/import your icon component
52+
components: {
53+
Input: async () => import(/* webpackChunkName: "input-component" */ "./components/Input"),
54+
},
55+
options: {
56+
base: [
57+
/*
58+
Declare settings to be added to the "Base settings" section
59+
of the field in the Content-Type Builder
60+
*/
61+
{
62+
sectionTitle: { // Add a "Format" settings section
63+
id: 'ai-text-generation.text-ai.api.details',
64+
defaultMessage: 'API Details',
65+
},
66+
items: [ // Add settings items to the section
67+
{
68+
/*
69+
Add a "Color format" dropdown
70+
to choose between 2 different format options
71+
for the color value: hexadecimal or RGBA
72+
*/
73+
intlLabel: {
74+
id: 'ai-text-generation.text-ai.key',
75+
defaultMessage: 'Key',
76+
},
77+
name: 'options.key',
78+
type: 'input',
79+
value: '', // option selected by default
80+
},
81+
],
82+
},
83+
],
84+
},
85+
});
86+
},
87+
88+
89+
90+
bootstrap(app) {},
91+
async registerTrads({ locales }) {
92+
const importedTrads = await Promise.all(
93+
locales.map((locale) => {
94+
return import(
95+
/* webpackChunkName: "translation-[request]" */ `./translations/${locale}.json`
96+
)
97+
.then(({ default: data }) => {
98+
return {
99+
data: prefixPluginTranslations(data, pluginId),
100+
locale,
101+
};
102+
})
103+
.catch(() => {
104+
return {
105+
data: {},
106+
locale,
107+
};
108+
});
109+
})
110+
);
111+
112+
return Promise.resolve(importedTrads);
113+
},
114+
};

admin/src/pages/App/index.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/**
2+
*
3+
* This component is the skeleton around the actual pages, and should only
4+
* contain code that should be seen on all pages. (e.g. navigation bar)
5+
*
6+
*/
7+
8+
import React from 'react';
9+
import { Switch, Route } from 'react-router-dom';
10+
import { NotFound } from '@strapi/helper-plugin';
11+
import pluginId from '../../pluginId';
12+
import HomePage from '../HomePage';
13+
14+
const App = () => {
15+
return (
16+
<div>
17+
<Switch>
18+
<Route path={`/plugins/${pluginId}`} component={HomePage} exact />
19+
<Route component={NotFound} />
20+
</Switch>
21+
</div>
22+
);
23+
};
24+
25+
export default App;

admin/src/pages/HomePage/index.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/*
2+
*
3+
* HomePage
4+
*
5+
*/
6+
7+
import React from 'react';
8+
// import PropTypes from 'prop-types';
9+
import pluginId from '../../pluginId';
10+
11+
const HomePage = () => {
12+
return (
13+
<div>
14+
<h1>{pluginId}&apos;s HomePage</h1>
15+
<p>Happy coding</p>
16+
</div>
17+
);
18+
};
19+
20+
export default HomePage;

admin/src/pluginId.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import pluginPkg from '../../package.json';
2+
3+
const pluginId = pluginPkg.name.replace(/^(@[^-,.][\w,-]+\/|strapi-)plugin-/i, '');
4+
5+
export default pluginId;

admin/src/translations/en.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{}

0 commit comments

Comments
 (0)