diff --git a/components/button.tsx b/components/button.tsx index 5a1cef3..3875a64 100644 --- a/components/button.tsx +++ b/components/button.tsx @@ -10,35 +10,64 @@ function ThemeToggle() { if (!mounted) return null; const toggleTheme = () => { - const targetTheme = resolvedTheme === "light" ? "dark" : "light"; - + const targetTheme = resolvedTheme === 'light' ? 'dark' : 'light'; setTheme(targetTheme); }; + const sliderStyle = { + width: '70px', + height: '25px', + borderRadius: '12.5px', + backgroundColor: resolvedTheme === 'dark' ? '#333' : '#ddd', + position: 'relative' as 'relative', + cursor: 'pointer', + transition: 'background-color 0.3s', + }; + + const knobStyle = { + width: '25px', + height: '25px', + borderRadius: '50%', + backgroundColor: resolvedTheme === 'dark' ? '#ddd' : '#333', + position: 'absolute' as 'absolute', + top: '50%', + transform: 'translateY(-50%)', + left: resolvedTheme === 'dark' ? '0' : '45px', + transition: 'left 0.3s, background-color 0.3s', + }; + + const textStyle = { + position: 'absolute' as 'absolute', + top: '50%', + transform: 'translateY(-50%)', + width: '100%', + textAlign: 'center', + fontSize: '14px', + fontWeight: 'bold', + color: resolvedTheme === 'dark' ? '#333' : '#ddd', + }; + return ( - +
+
+
{resolvedTheme === 'dark' ? 'Dark' : 'Light'}
+
+
+
); } export default ThemeToggle; - - - diff --git a/components/logo.tsx b/components/logo.tsx new file mode 100644 index 0000000..d9e73a2 --- /dev/null +++ b/components/logo.tsx @@ -0,0 +1,12 @@ +// components/logo.tsx +import React from 'react'; + +const Logo = () => { + return ( +
+ ArtiGenius-AI +
+ ); +}; + +export default Logo; diff --git a/components/prompt-form.tsx b/components/prompt-form.tsx index 5ad4fb1..ba5383f 100644 --- a/components/prompt-form.tsx +++ b/components/prompt-form.tsx @@ -1,8 +1,10 @@ -import React from 'react'; +import React, { useState, useRef } from 'react'; import { useTheme } from 'next-themes'; import * as Form from '@radix-ui/react-form'; import { styled } from '@stitches/react'; +const fontFamily = "'Poppins', sans-serif"; + type Props = { onSubmit: (prompt: string) => void; isGenerating: boolean; @@ -14,6 +16,50 @@ export const PromptForm: React.FC = ({ onSubmit, isGenerating }) => { const { theme, resolvedTheme } = useTheme(); const currentTheme: ThemeVariants = (theme || resolvedTheme || 'light') as ThemeVariants; + const [randomPrompt, setRandomPrompt] = useState(null); + const promptInputRef = useRef(null); + + const handleSurpriseMeClick = (e: React.MouseEvent) => { + e.preventDefault(); + + //An array of random prompts + const randomPrompts = [ + 'A beautiful sunset over the ocean', + 'A cozy cabin in the woods', + 'A futuristic cityscape', + 'A beautiful sunset over the ocean', + 'A cozy cabin in the woods', + 'A futuristic cityscape', + 'An enchanted forest with talking animals', + 'A bustling market in a foreign land', + 'A magical kingdom hidden in the clouds', + 'A secret underground laboratory', + 'A time-traveling adventure to the past', + 'Exploring an alien planet with strange creatures', + 'A pirate ship sailing the high seas', + 'A haunted house on a dark and stormy night', + 'An epic battle between dragons and knights', + 'A journey through a mysterious portal', + 'A hidden treasure map leading to riches', + 'A deserted island with a message in a bottle', + 'A parallel universe with alternate versions of yourself', + 'A quest to save the world from an evil sorcerer', + 'A trip to the moon in a rocket ship', + 'A magical spell that goes awry', + 'A visit to a futuristic city of robots', + + ]; + + + const randomIndex = Math.floor(Math.random() * randomPrompts.length); + const randomPrompt = randomPrompts[randomIndex]; + + + if (promptInputRef.current) { + promptInputRef.current.value = randomPrompt; + } + }; + const handleSubmit: React.FormEventHandler = (e) => { e.preventDefault(); @@ -33,6 +79,7 @@ export const PromptForm: React.FC = ({ onSubmit, isGenerating }) => { = ({ onSubmit, isGenerating }) => { /> - - - {isGenerating ? 'Generating..' : 'Start Generating'} + + + + {isGenerating ? 'Generating..' : 'Start Generating'} + + + + Surprise Me - + ); }; @@ -61,12 +117,14 @@ const StyledFormLabel = styled(Form.Label, { fontWeight: 500, lineHeight: '35px', color: '$foreground', + fontFamily: fontFamily, }); const StyledFormMessage = styled(Form.Message, { fontSize: 13, color: '$red600', opacity: 0.8, + fontFamily: fontFamily, }); const StyledFlex = styled('div', { display: 'flex' }); @@ -87,6 +145,7 @@ const inputStyles = { '&:hover': { boxShadow: '0 0 0 1px $gray600' }, '&:focus': { boxShadow: '0 0 0 2px $purple600' }, '&::selection': { backgroundColor: '$gray600', color: 'white' }, + fontFamily: fontFamily, }; const StyledInput = styled('input', { @@ -94,6 +153,7 @@ const StyledInput = styled('input', { height: 35, lineHeight: 1, padding: '0 10px', + borderRadius: 15, variants: { theme: { dark: { @@ -133,4 +193,5 @@ const StyledButton = styled('button', { boxShadow: '0 2px 10px $gray400', '&:not(:disabled):hover': { backgroundColor: '$purple600' }, '&:not(:disabled):focus': { boxShadow: '0 0 0 2px black' }, + fontFamily: fontFamily, }); diff --git a/pages/index.tsx b/pages/index.tsx index e8af883..05da6ae 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -1,109 +1,138 @@ -import Head from 'next/head' -import { styled } from '../stitches.config' -import { PromptForm } from '../components/prompt-form' -import { useState } from 'react' -import { Output } from '../components/output' -import { darkTheme } from "../stitches.config"; +import Head from 'next/head'; +import { styled } from '../stitches.config'; +import { PromptForm } from '../components/prompt-form'; +import { useState } from 'react'; +import { Output } from '../components/output'; +import { darkTheme } from '../stitches.config'; +import Logo from '../components/logo'; +import ThemeToggle from '../components/button'; -const Box = styled('div', {}) +const Box = styled('div', {}); const Text = styled('p', { - fontFamily: '$system', - color: '$hiContrast', -}) + fontFamily: '$system', + color: '$hiContrast', +}); + +const LogoWrapper = styled('div', { + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + marginTop: 'auto', +}); const Container = styled('div', { - marginX: 'auto', - paddingX: '$3', - - variants: { - size: { - 1: { - maxWidth: '300px', - }, - 2: { - maxWidth: '585px', - }, - 3: { - maxWidth: '865px', - }, - }, + marginX: 'auto', + paddingX: '$3', + + variants: { + size: { + 1: { + maxWidth: '300px', + }, + 2: { + maxWidth: '585px', + }, + 3: { + maxWidth: '865px', + }, }, -}) + }, +}); + +const PageContainer = styled('div', { + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + justifyContent: 'center', + minHeight: '100vh', + position: 'relative', +}); + +const LogoText = styled('h2', { + fontFamily: 'Poppins, sans-serif', + fontSize: '50px', + fontWeight: 'bold', + color: darkTheme ? '$white' : '$loContrast', + margin: '0', +}); export default function Home() { - const [isGenerating, setIsGenerating] = useState(false) - const [output, setOutput] = useState(null) - - const handleStartGeneration = async (prompt: string) => { - if (typeof prompt != 'string') { - alert('Invalid prompt') - return - } - - setOutput(null) - setIsGenerating(true) - - try { - const response = await generateImage(prompt) - const blob: Blob = await response.blob() - setOutput(URL.createObjectURL(blob)) - } catch (error) { - console.error(error) - } finally { - setIsGenerating(false) - } + const [isGenerating, setIsGenerating] = useState(false); + const [output, setOutput] = useState(null); + + const handleStartGeneration = async (prompt: string) => { + if (typeof prompt !== 'string') { + alert('Invalid prompt'); + return; } - const generateImage = async (prompt: string) => { - const myHeaders = new Headers() - myHeaders.append('Content-Type', 'application/json') - myHeaders.append( - 'Authorization', - `Bearer ${process.env.NEXT_PUBLIC_HUGGINGFACE_API_KEY}`, - ) - - const response = await fetch( - 'https://api-inference.huggingface.co/models/runwayml/stable-diffusion-v1-5', - { - method: 'POST', - headers: myHeaders, - body: JSON.stringify({ - inputs: prompt, - }), - redirect: 'follow', - }, - ) - - if (!response.ok) { - throw new Error('Failed to generate image') - } - - return response + setOutput(null); + setIsGenerating(true); + + try { + const response = await generateImage(prompt); + const blob: Blob = await response.blob(); + setOutput(URL.createObjectURL(blob)); + } catch (error) { + console.error(error); + } finally { + setIsGenerating(false); } + }; + + const generateImage = async (prompt: string) => { + const myHeaders = new Headers(); + myHeaders.append('Content-Type', 'application/json'); + myHeaders.append( + 'Authorization', + `Bearer ${process.env.NEXT_PUBLIC_HUGGINGFACE_API_KEY}` + ); + + const response = await fetch( + 'https://api-inference.huggingface.co/models/runwayml/stable-diffusion-v1-5', + { + method: 'POST', + headers: myHeaders, + body: JSON.stringify({ + inputs: prompt, + }), + redirect: 'follow', + } + ); + + if (!response.ok) { + throw new Error('Failed to generate image'); + } + + return response; + }; - return ( - - - ArtiGenius-AI - - - - Create realistic images and art from a description in natural language - - - - {output && Generated Image} - - - - ) + return ( + + + + + ArtiGenius-AI + + + + ArtiGenius-AI + + + + Generate lifelike images from your text prompts with precision and realism. + + + {output && Generated Image} + + + + ); } diff --git a/public/favicon.ico b/public/favicon.ico index 4965832..cfd38d9 100644 Binary files a/public/favicon.ico and b/public/favicon.ico differ diff --git a/public/logo1-removebg-preview.png b/public/logo1-removebg-preview.png new file mode 100644 index 0000000..0f0f7e0 Binary files /dev/null and b/public/logo1-removebg-preview.png differ diff --git a/public/logo1.png b/public/logo1.png new file mode 100644 index 0000000..675e86c Binary files /dev/null and b/public/logo1.png differ diff --git a/public/logo2-removebg-preview.png b/public/logo2-removebg-preview.png new file mode 100644 index 0000000..d254aad Binary files /dev/null and b/public/logo2-removebg-preview.png differ diff --git a/public/logo2.png b/public/logo2.png new file mode 100644 index 0000000..c00609d Binary files /dev/null and b/public/logo2.png differ diff --git a/public/logo3-removebg-preview.png b/public/logo3-removebg-preview.png new file mode 100644 index 0000000..95010d6 Binary files /dev/null and b/public/logo3-removebg-preview.png differ diff --git a/public/logo3.png b/public/logo3.png new file mode 100644 index 0000000..f45280b Binary files /dev/null and b/public/logo3.png differ diff --git a/public/logo4-removebg-preview.png b/public/logo4-removebg-preview.png new file mode 100644 index 0000000..755455a Binary files /dev/null and b/public/logo4-removebg-preview.png differ diff --git a/public/logo4.png b/public/logo4.png new file mode 100644 index 0000000..cfd38d9 Binary files /dev/null and b/public/logo4.png differ diff --git a/public/logo5-removebg-preview.png b/public/logo5-removebg-preview.png new file mode 100644 index 0000000..3a668f5 Binary files /dev/null and b/public/logo5-removebg-preview.png differ diff --git a/public/logo5.png b/public/logo5.png new file mode 100644 index 0000000..0af499c Binary files /dev/null and b/public/logo5.png differ diff --git a/public/logo6.png b/public/logo6.png new file mode 100644 index 0000000..1b9199e Binary files /dev/null and b/public/logo6.png differ diff --git a/public/logo7-removebg-preview.png b/public/logo7-removebg-preview.png new file mode 100644 index 0000000..d02a51c Binary files /dev/null and b/public/logo7-removebg-preview.png differ diff --git a/public/logo7.png b/public/logo7.png new file mode 100644 index 0000000..ff95e25 Binary files /dev/null and b/public/logo7.png differ