Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Darkmode #14

Merged
merged 11 commits into from
Mar 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,6 @@ module.exports = {
patterns: ['@mui/*/*/*'],
},
],
'@typescript-eslint/no-explicit-any': 'off',
},
};
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# AI Form Toolkit
# GPTBundle

Build and enhance your React forms with Artificial Intelligence. Integrated with Next.js server actions for maximum productivity.

AI Form Toolkit facilitates adding AI capabilities to forms in React applications:
GPTBundle facilitates adding AI capabilities to forms in React applications:

- For your Product – autogenerate forms from existing content: checklists, surveys, exams, data collection, you name it!
- For your Users – help users fill your product forms with AI-powered autofill capabilities.
Expand All @@ -15,10 +15,10 @@ Note that hosted examples are not interactive. See [Building](#building) below t

## Project Structure

This is a multipackage monorepo that holds the two NPM projects necessary for AI Form Toolkit:
This is a multipackage monorepo that holds the two NPM projects necessary for GPTBundle:

- `@ai-form-toolkit/client`
- `@ai-form-toolkit/server`
- `@gptbundle/client`
- `@gptbundle/server`

Both are stored at `packages/` directory.

Expand Down Expand Up @@ -50,7 +50,7 @@ OPENAI_API_KEY=sk-...
Run the docs project:

```bash
pnpm -F ai-form-toolkit-docs run dev
pnpm -F @gptbundle/docs run dev
```

Then open `http://localhost:3000` in your browser.
Expand Down
9 changes: 5 additions & 4 deletions docs/package.json
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
{
"name": "ai-form-toolkit-docs",
"name": "@gptbundle/docs",
"version": "0.0.1",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"prebuild": "pnpm -F @gptbundle/server build && pnpm -F @gptbundle/client build",
"build": "pnpm run prebuild && next build",
"analyze": "ANALYZE=true next build",
"start": "next start"
},
"dependencies": {
"@ai-form-toolkit/client": "file:../packages/client",
"@ai-form-toolkit/server": "file:../packages/server",
"@gptbundle/client": "workspace:../packages/client",
"@gptbundle/server": "workspace:../packages/server",
"@emotion/react": "^11.11.3",
"@emotion/styled": "^11.11.0",
"@mdx-js/react": "^3.0.0",
Expand Down
1 change: 0 additions & 1 deletion docs/public/favicon.svg

This file was deleted.

Binary file added docs/public/favicon.webp
Binary file not shown.
3 changes: 3 additions & 0 deletions docs/src/MDXProviderWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ const MDXProviderWrapper = ({ children }: { children: ReactNode }) => {
h2: (props: HTMLAttributes<HTMLElement>) => <Typography component="h2" variant="h5" marginY={2} {...props} />,
h3: (props: HTMLAttributes<HTMLElement>) => <Typography component="h3" variant="h6" marginY={2} {...props} />,
p: (props: HTMLAttributes<HTMLElement>) => <Typography component="p" variant="body1" marginY={2} {...props} />,
a: (props: HTMLAttributes<HTMLElement>) => (
<Typography component="a" variant="body1" marginY={2} style={{ color: '#00f0ff', fontWeight: 600 }} {...props} />
),
};

return <MDXProvider components={components}>{children}</MDXProvider>;
Expand Down
34 changes: 34 additions & 0 deletions docs/src/MuiThemeWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,41 @@ import { CssBaseline } from '@mui/material';

const MuiThemeWrapper = ({ children }: { children: ReactNode }) => {
const theme = createTheme({
palette: {
mode: 'dark',
primary: {
main: '#00F0FF',
dark: '#1766FF',
},
secondary: {
light: '#9E8FFF',
main: '#995AFF',
dark: '#15023D',
},
background: {
default: '#130B2F',
},
},
typography: {
fontFamily: 'DM Sans, sans-serif', // Set default font
},
components: {
MuiCssBaseline: {
styleOverrides: `
h1 {
margin-bottom: 48px!important;
}
h2 {
font-weight: 600!important;
}
h2,h3 {
margin-top: 32px!important;
}
p, li {
line-height: 26.5px!important;
}
`,
},
MuiButton: {
styleOverrides: {
root: {
Expand Down
44 changes: 1 addition & 43 deletions docs/src/app/docs-layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import { ReactNode } from 'react';
import { Box } from '@mui/material';
import { GlobalStyles } from '@mui/system';
import { Theme } from '@mui/material/styles';
import docsMarkdownStyles from './docs-markdown-styles';

import Layout from '@/layout';

Expand All @@ -12,48 +12,6 @@ type Props = {
};

export default function DocsLayout({ children }: Props) {
const docsMarkdownStyles = (theme: Theme) => ({
figure: {
margin: 0,
},
pre: {
overflowX: 'auto',
borderRadius: theme.shape.borderRadius,
padding: `${theme.spacing(1)} ${theme.spacing(0.5)}`,
},
'span[data-highlighted-line]': {
borderBottomColor: '#9333EA',
backgroundColor: '#6B21A880',
fontWeight: 700,
color: '#E9D5FF',
},
// TODO: Use CodeBlock component instead. Configure it on MDXProviderWrapper.
code: {
counterReset: 'line',
fontSize: '0.8125rem',
},
'code > [data-line]::before': {
counterIncrement: 'line',
content: 'counter(line)',
display: 'inline-block',
width: theme.spacing(1),
marginRight: theme.spacing(1.5),
textAlign: 'right',
color: 'gray',
},
'code[data-line-numbers-max-digits="2"] > [data-line]::before': {
width: theme.spacing(2),
},
'code[data-line-numbers-max-digits="3"] > [data-line]::before': {
width: theme.spacing(3),
},
img: {
width: '100%',
height: 'auto',
border: `2px solid ${theme.palette.grey[200]}`,
},
});

return (
<>
<GlobalStyles styles={docsMarkdownStyles} />
Expand Down
48 changes: 48 additions & 0 deletions docs/src/app/docs-markdown-styles.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
'use client';

import { Theme } from '@mui/material/styles';

const docsMarkdownStyles = (theme: Theme) => ({
figure: {
margin: 0,
},
pre: {
overflowX: 'auto',
borderRadius: theme.shape.borderRadius,
backgroundColor: '#12111a!important',
padding: `${theme.spacing(1)} ${theme.spacing(0.5)}`,
},
'span[data-highlighted-line]': {
borderBottomColor: '#9333EA',
backgroundColor: '#6B21A880',
fontWeight: 700,
color: '#E9D5FF',
},
// TODO: Use CodeBlock component instead. Configure it on MDXProviderWrapper.
code: {
counterReset: 'line',
fontSize: '0.8125rem',
},
'code > [data-line]::before': {
counterIncrement: 'line',
content: 'counter(line)',
display: 'inline-block',
width: theme.spacing(1),
marginRight: theme.spacing(1.5),
textAlign: 'right',
color: 'gray',
},
'code[data-line-numbers-max-digits="2"] > [data-line]::before': {
width: theme.spacing(2),
},
'code[data-line-numbers-max-digits="3"] > [data-line]::before': {
width: theme.spacing(3),
},
img: {
width: '100%',
height: 'auto',
border: `2px solid ${theme.palette.grey[200]}`,
},
});

export default docsMarkdownStyles;
18 changes: 18 additions & 0 deletions docs/src/app/examples/assistant/form-assistant/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
'use client';

import { Box } from '@mui/material';
import SingleFieldFormAssistant from '../single-field-assistant/page';
import MultiFieldFormAssistant from '../multi-field-assistant/page';
import ExamSchemaGenWithAssistantExample from '../gen-with-assistant/page';

function FieldAssistantList() {
return (
<Box>
<SingleFieldFormAssistant />
<MultiFieldFormAssistant />
<ExamSchemaGenWithAssistantExample />
</Box>
);
}

export default FieldAssistantList;
30 changes: 14 additions & 16 deletions docs/src/app/examples/assistant/gen-with-assistant/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,15 @@ import { LoadingButton } from '@mui/lab';
import ListAltOutlinedIcon from '@mui/icons-material/ListAltOutlined';
import PsychologyOutlinedIcon from '@mui/icons-material/PsychologyOutlined';

import { useGeneratedFormSchema, useFormAssistant } from '@ai-form-toolkit/client';
import { useRequestDialog } from '../../../requestDialog';
import { useGeneratedFormSchema, useFormAssistant } from '@gptbundle/client';
import LoadingBackdrop from '@/components/Examples/LoadingBackdrop';
import SchemaFormDemo from '@/components/Forms/SchemaFormDemo';
import { h2Styles, boxForms } from '../../../../app/examples/formStyles';

export default function ExamSchemaGenWithAssistantExample() {
const { requestDialog, renderDialog, isLoading } = useRequestDialog();

const defaultContent = dedent`
Technical Requirements for the job:
Frontend:
Expand All @@ -34,7 +38,6 @@ export default function ExamSchemaGenWithAssistantExample() {
const [content, setContent] = useState(defaultContent);
const [prompt, setPrompt] = useState(defaultPrompt);
const { formSchema, uiSchema, generateFormSchema } = useGeneratedFormSchema();
const [isLoading, setIsLoading] = useState(false);

const fieldToFill = Object.keys(formSchema?.properties || {})[0] || null;
const fieldLabels = Object.entries(formSchema?.properties || {}).reduce((acc, [key, value]) => {
Expand All @@ -57,19 +60,19 @@ export default function ExamSchemaGenWithAssistantExample() {
};

return (
<Stack spacing={2}>
<Stack spacing={2} sx={{ ...boxForms }}>
<Stack spacing={2}>
<LoadingBackdrop open={isLoading} />

<Typography variant="h4">Generate and then autofill form:</Typography>
<Typography variant="h2" sx={{ ...h2Styles }}>
Generate Form Button + Auto-Fill Form:
</Typography>
<Typography variant="body1">
Code at <code>docs/src/app/examples/assistant/gen-with-assistant/page.tsx</code>
</Typography>
<Typography variant="body1">
This form combines <code>useGeneratedFormSchema</code> with <code>useFormAssistant</code> hooks to generate a
form from content + prompt, and then support GPT-4 autofill on it.
</Typography>

<TextField
multiline
fullWidth
Expand Down Expand Up @@ -98,10 +101,7 @@ export default function ExamSchemaGenWithAssistantExample() {
loadingPosition="start"
loading={isLoading}
startIcon={<PsychologyOutlinedIcon />}
onClick={() => {
setIsLoading(true);
fillSingleField(fieldToFill).finally(() => setIsLoading(false));
}}
onClick={() => requestDialog(() => fillSingleField(fieldToFill))}
>
Autofill missing with GPT-4
</LoadingButton>
Expand All @@ -111,10 +111,7 @@ export default function ExamSchemaGenWithAssistantExample() {
loadingPosition="start"
loading={isLoading}
startIcon={<ListAltOutlinedIcon />}
onClick={() => {
setIsLoading(true);
generateFormSchema(content, prompt).finally(() => setIsLoading(false));
}}
onClick={() => requestDialog(() => generateFormSchema(content, prompt))}
>
Generate Form
</LoadingButton>
Expand All @@ -124,11 +121,12 @@ export default function ExamSchemaGenWithAssistantExample() {
formSchema={formSchema}
uiSchema={uiSchema}
onSubmit={onSubmit}
// @ts-ignore
// @ts-expect-error - code sample
formData={formValues}
// @ts-ignore
// @ts-expect-error - code sample
onChange={(e) => setFormValues(e.formValues)}
/>
{renderDialog()}
</Stack>
);
}
20 changes: 12 additions & 8 deletions docs/src/app/examples/assistant/multi-field-assistant/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,15 @@ import { LoadingButton } from '@mui/lab';
import AutoFixHighOutlinedIcon from '@mui/icons-material/AutoFixHighOutlined';
import PsychologyOutlinedIcon from '@mui/icons-material/PsychologyOutlined';

import { useFormAssistant } from '@ai-form-toolkit/client';
import { useRequestDialog } from '../../../requestDialog';
import { useFormAssistant } from '@gptbundle/client';
import { h2Styles, boxForms } from '../../../../app/examples/formStyles';

const CATEGORY_CHOICES = ['Bug', 'Feature', 'Improvement'];
const PRIORITY_CHOICES = ['High', 'Medium', 'Low'];

export default function MultiFieldFormAssistant() {
const { requestDialog, renderDialog, isLoading } = useRequestDialog();
const [formValues, setFormValues] = useState<Record<string, string>>({
title: 'Fix N+1s in Django codebase',
description: 'Use prefetch...',
Expand All @@ -32,7 +35,7 @@ export default function MultiFieldFormAssistant() {
priority: PRIORITY_CHOICES,
},
});
const [isLoading, setIsLoading] = useState(false);

const [isLoadingDescription, setIsLoadingDescription] = useState(false);

const handleInputChange = (name: string, value: string | null) => {
Expand All @@ -44,12 +47,13 @@ export default function MultiFieldFormAssistant() {

const handleSubmit = (event: FormEvent) => {
event.preventDefault();
console.log(formValues);
};

return (
<Stack spacing={2}>
<Typography variant="h4">GPT-4 form assistant (multi field)</Typography>
<Stack spacing={2} sx={{ ...boxForms }}>
<Typography variant="h2" sx={{ ...h2Styles }}>
Multi field Form
</Typography>
<Typography variant="body1">
Code at <code>docs/src/app/examples/assistant/multi-field-assistant/page.tsx</code>
</Typography>
Expand Down Expand Up @@ -144,18 +148,18 @@ export default function MultiFieldFormAssistant() {
startIcon={<PsychologyOutlinedIcon />}
disabled={isLoading || isLoadingDescription}
onClick={() => {
setIsLoading(true);
fillFields().finally(() => setIsLoading(false));
requestDialog(() => fillFields());
}}
>
Autofill missing with GPT-4
</LoadingButton>
<Button type="submit" variant="contained">
<Button type="submit" variant="contained" disabled={isLoading}>
Submit
</Button>
</Stack>
</Stack>
</form>
{renderDialog()}
</Stack>
);
}
Loading
Loading