code-translator / pages /index.tsx
khulnasoft's picture
Upload 24 files
8e20687 verified
import { APIKeyInput } from '@/components/APIKeyInput';
import { CodeBlock } from '@/components/CodeBlock';
import { LanguageSelect } from '@/components/LanguageSelect';
import { ModelSelect } from '@/components/ModelSelect';
import { TextBlock } from '@/components/TextBlock';
import { OpenAIModel, TranslateBody } from '@/types/types';
import Head from 'next/head';
import { useEffect, useState } from 'react';
export default function Home() {
const [inputLanguage, setInputLanguage] = useState<string>('JavaScript');
const [outputLanguage, setOutputLanguage] = useState<string>('Python');
const [inputCode, setInputCode] = useState<string>('');
const [outputCode, setOutputCode] = useState<string>('');
const [model, setModel] = useState<OpenAIModel>('gpt-3.5-turbo');
const [loading, setLoading] = useState<boolean>(false);
const [hasTranslated, setHasTranslated] = useState<boolean>(false);
const [apiKey, setApiKey] = useState<string>('');
const handleTranslate = async () => {
const maxCodeLength = model === 'gpt-3.5-turbo' ? 6000 : 12000;
if (!apiKey) {
alert('Please enter an API key.');
return;
}
if (inputLanguage === outputLanguage) {
alert('Please select different languages.');
return;
}
if (!inputCode) {
alert('Please enter some code.');
return;
}
if (inputCode.length > maxCodeLength) {
alert(
`Please enter code less than ${maxCodeLength} characters. You are currently at ${inputCode.length} characters.`,
);
return;
}
setLoading(true);
setOutputCode('');
const controller = new AbortController();
const body: TranslateBody = {
inputLanguage,
outputLanguage,
inputCode,
model,
apiKey,
};
const response = await fetch('/api/translate', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
signal: controller.signal,
body: JSON.stringify(body),
});
if (!response.ok) {
setLoading(false);
alert('Something went wrong.');
return;
}
const data = response.body;
if (!data) {
setLoading(false);
alert('Something went wrong.');
return;
}
const reader = data.getReader();
const decoder = new TextDecoder();
let done = false;
let code = '';
while (!done) {
const { value, done: doneReading } = await reader.read();
done = doneReading;
const chunkValue = decoder.decode(value);
code += chunkValue;
setOutputCode((prevCode) => prevCode + chunkValue);
}
setLoading(false);
setHasTranslated(true);
copyToClipboard(code);
};
const copyToClipboard = (text: string) => {
const el = document.createElement('textarea');
el.value = text;
document.body.appendChild(el);
el.select();
document.execCommand('copy');
document.body.removeChild(el);
};
const handleApiKeyChange = (value: string) => {
setApiKey(value);
localStorage.setItem('apiKey', value);
};
useEffect(() => {
if (hasTranslated) {
handleTranslate();
}
}, [outputLanguage]);
useEffect(() => {
const apiKey = localStorage.getItem('apiKey');
if (apiKey) {
setApiKey(apiKey);
}
}, []);
return (
<>
<Head>
<title>Code Translator</title>
<meta
name="description"
content="Use AI to translate code from one language to another."
/>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" href="/favicon.ico" />
</Head>
<div className="flex h-full min-h-screen flex-col items-center bg-[#0E1117] px-4 pb-20 text-neutral-200 sm:px-10">
<div className="mt-10 flex flex-col items-center justify-center sm:mt-20">
<div className="text-4xl font-bold">AI Code Translator</div>
</div>
<div className="mt-6 text-center text-sm">
<APIKeyInput apiKey={apiKey} onChange={handleApiKeyChange} />
</div>
<div className="mt-2 flex items-center space-x-2">
<ModelSelect model={model} onChange={(value) => setModel(value)} />
<button
className="w-[140px] cursor-pointer rounded-md bg-violet-500 px-4 py-2 font-bold hover:bg-violet-600 active:bg-violet-700"
onClick={() => handleTranslate()}
disabled={loading}
>
{loading ? 'Translating...' : 'Translate'}
</button>
</div>
<div className="mt-2 text-center text-xs">
{loading
? 'Translating...'
: hasTranslated
? 'Output copied to clipboard!'
: 'Enter some code and click "Translate"'}
</div>
<div className="mt-6 flex w-full max-w-[1200px] flex-col justify-between sm:flex-row sm:space-x-4">
<div className="h-100 flex flex-col justify-center space-y-2 sm:w-2/4">
<div className="text-center text-xl font-bold">Input</div>
<LanguageSelect
language={inputLanguage}
onChange={(value) => {
setInputLanguage(value);
setHasTranslated(false);
setInputCode('');
setOutputCode('');
}}
/>
{inputLanguage === 'Natural Language' ? (
<TextBlock
text={inputCode}
editable={!loading}
onChange={(value) => {
setInputCode(value);
setHasTranslated(false);
}}
/>
) : (
<CodeBlock
code={inputCode}
editable={!loading}
onChange={(value) => {
setInputCode(value);
setHasTranslated(false);
}}
/>
)}
</div>
<div className="mt-8 flex h-full flex-col justify-center space-y-2 sm:mt-0 sm:w-2/4">
<div className="text-center text-xl font-bold">Output</div>
<LanguageSelect
language={outputLanguage}
onChange={(value) => {
setOutputLanguage(value);
setOutputCode('');
}}
/>
{outputLanguage === 'Natural Language' ? (
<TextBlock text={outputCode} />
) : (
<CodeBlock code={outputCode} />
)}
</div>
</div>
</div>
</>
);
}