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

added eslint and prettier #5

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
4 changes: 4 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"extends": ["next/core-web-vitals", "prettier"],
"rules": { "no-unused-vars": "warn" }
}
6 changes: 6 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"trailingComma": "es5",
"tabWidth": 2,
"semi": true,
"singleQuote": true
}
14 changes: 9 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
</a>
</p>


This project generates almost any UI components with OpenAI's ChatGPT and allows you to copy the html code

[![Twitter Bio Generator](./public/screenshot.png)](https://ai2ui.co)
Expand All @@ -20,12 +19,13 @@ This project generates almost any UI components with OpenAI's ChatGPT and allows

## How it works

This project uses the [ChatGPT API](https://openai.com/api/) and [Vercel Edge functions](https://vercel.com/features/edge-functions).
This project uses the [ChatGPT API](https://openai.com/api/) and [Vercel Edge functions](https://vercel.com/features/edge-functions).
It constructs a prompt based on the form and user input, sends it to the chatGPT API via a Vercel Edge function, then streams the response back to the application.
You can ask for any UI component, free style. Most likely it will generate the right thing for you.
This can also be used as a great bootstrap for projects, I tried to make the style Material-UI styled, but you can change this behavior.

## Running Locally

This project is built with `Next.js` and `TailwindCSS`, so you can deploy it directly to Vercel.

After cloning the repo, go to [OpenAI](https://beta.openai.com/account/api-keys) to make an account and put your API key in a file called `.env`(OPENAI_API_KEY)
Expand All @@ -38,6 +38,7 @@ yarn dev
```

## Changing ChatGPT prompts and requests

In order to change ChatGPT response you only need to give it an example of what you wish to get back (use the assistant role to generate an example of a good response)".
In the example below I show it how to generate TailwindCSS and Next.js component, and later ask just to return the corresponding HTML code.

Expand Down Expand Up @@ -95,13 +96,16 @@ const handler = async (req: Request): Promise<Response> => {
My name is [Yuval](https://www.linkedin.com/in/yuval-suede/) - an entrepreneur at heart , I ❤️ building end-to-end systems that not only look amazing and feel state-of-the-art, but also have real meaning and impact.

## 🤝 Contributing

Contributions, issues and feature requests are welcome!<br />
* Fork the repository, Clone it on your device. That's it 🎉
* Finally make a pull request :)

- Fork the repository, Clone it on your device. That's it 🎉
- Finally make a pull request :)

## 📝 License

This project is [MIT License](https://opensource.org/licenses/MIT) licensed.

***
---

We accept contribution with great love! Show your interest! Contribute!
18 changes: 9 additions & 9 deletions components/DropDown.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
import { Menu, Transition } from "@headlessui/react";
import { Menu, Transition } from '@headlessui/react';
import {
CheckIcon,
ChevronDownIcon,
ChevronUpIcon,
} from "@heroicons/react/20/solid";
import { Fragment } from "react";
} from '@heroicons/react/20/solid';
import { Fragment } from 'react';

function classNames(...classes: string[]) {
return classes.filter(Boolean).join(" ");
return classes.filter(Boolean).join(' ');
}

export type VibeType = "Junior" | "Senior";
export type VibeType = 'Junior' | 'Senior';

interface DropDownProps {
vibe: VibeType;
setVibe: (vibe: VibeType) => void;
}

let vibes: VibeType[] = ["Junior", "Senior"];
let vibes: VibeType[] = ['Junior', 'Senior'];

export default function DropDown({ vibe, setVibe }: DropDownProps) {
return (
Expand Down Expand Up @@ -56,9 +56,9 @@ export default function DropDown({ vibe, setVibe }: DropDownProps) {
<button
onClick={() => setVibe(vibeItem)}
className={classNames(
active ? "bg-gray-100 text-gray-900" : "text-gray-700",
vibe === vibeItem ? "bg-gray-200" : "",
"px-4 py-2 text-sm w-full text-left flex items-center space-x-2 justify-between"
active ? 'bg-gray-100 text-gray-900' : 'text-gray-700',
vibe === vibeItem ? 'bg-gray-200' : '',
'px-4 py-2 text-sm w-full text-left flex items-center space-x-2 justify-between'
)}
>
<span>{vibeItem}</span>
Expand Down
52 changes: 25 additions & 27 deletions components/Footer.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,27 @@
import Link from "next/link";

export default function Footer() {
return (
<footer
className="text-center h-16 sm:h-20 w-full sm:pt-2 pt-4 border-t mt-5 flex sm:flex-row flex-col justify-between items-center px-3 space-y-3 sm:mb-0 mb-3">
<div>
By{" "}
<a
href="https://www.linkedin.com/in/yuval-suede/"
target="_blank"
rel="noreferrer"
className="font-bold hover:underline transition underline-offset-2"
>
Yuval Suede
</a>
(contact me to suggest improvements).
</div>
<div className="sm:text-right ">
<div className="h-16 sm:h-20 w-full ">
<img className="h-full w-auto object-contain"
src="/ai-component-generator-logo.png" alt=""/>
</div>

</div>
</footer>

);
return (
<footer className="text-center h-16 sm:h-20 w-full sm:pt-2 pt-4 border-t mt-5 flex sm:flex-row flex-col justify-between items-center px-3 space-y-3 sm:mb-0 mb-3">
<div>
By{' '}
<a
href="https://www.linkedin.com/in/yuval-suede/"
target="_blank"
rel="noreferrer"
className="font-bold hover:underline transition underline-offset-2"
>
Yuval Suede
</a>
(contact me to suggest improvements).
</div>
<div className="sm:text-right ">
<div className="h-16 sm:h-20 w-full ">
<img
className="h-full w-auto object-contain"
src="/ai-component-generator-logo.png"
alt=""
/>
</div>
</div>
</footer>
);
}
7 changes: 4 additions & 3 deletions components/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import Image from "next/image";
import Link from "next/link";
import Image from 'next/image';
import Link from 'next/link';

export default function Header() {
return (
<header className="flex justify-between items-center w-full mt-5 border-b-2 pb-7 sm:px-4 px-2">
<Link href="/" className="flex space-x-3">
<h1 className="sm:text-4xl text-2xl font-bold ml-2 tracking-tight">
AI <span style={{ color: '#1A6292'}}>component </span>generator
AI <span style={{ color: '#1A6292' }}>component </span>
generator
</h1>
</Link>
<a
Expand Down
10 changes: 5 additions & 5 deletions components/LoadingDots.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import styles from "../styles/loading-dots.module.css";
import styles from '../styles/loading-dots.module.css';

const LoadingDots = ({
color = "#000",
style = "small",
color = '#000',
style = 'small',
}: {
color: string;
style: string;
}) => {
return (
<span className={style == "small" ? styles.loading2 : styles.loading}>
<span className={style == 'small' ? styles.loading2 : styles.loading}>
<span style={{ backgroundColor: color }} />
<span style={{ backgroundColor: color }} />
<span style={{ backgroundColor: color }} />
Expand All @@ -19,5 +19,5 @@ const LoadingDots = ({
export default LoadingDots;

LoadingDots.defaultProps = {
style: "small",
style: 'small',
};
8 changes: 4 additions & 4 deletions components/ResizablePanel.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { motion } from "framer-motion";
import useMeasure from "react-use-measure";
import { motion } from 'framer-motion';
import useMeasure from 'react-use-measure';

export default function ResizablePanel({
children,
Expand All @@ -13,9 +13,9 @@ export default function ResizablePanel({
animate={height ? { height } : {}}
style={height ? { height } : {}}
className="relative w-full overflow-hidden"
transition={{ type: "tween", duration: 0.5 }}
transition={{ type: 'tween', duration: 0.5 }}
>
<div ref={ref} className={height ? "absolute inset-x-0" : "relative"}>
<div ref={ref} className={height ? 'absolute inset-x-0' : 'relative'}>
{children}
</div>
</motion.div>
Expand Down
3 changes: 1 addition & 2 deletions next.config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
/** @type {import('next').NextConfig} */
module.exports = {
// reactStrictMode: true,
}

};
Loading