├── .gitignore ├── README.md ├── app ├── api │ └── generate │ │ └── route.tsx ├── favicon.ico ├── globals.css ├── layout.tsx └── page.tsx ├── components.json ├── next.config.ts ├── package-lock.json ├── package.json ├── postcss.config.mjs ├── public ├── file.svg ├── globe.svg ├── next.svg ├── vercel.svg └── window.svg ├── tailwind.config.ts └── tsconfig.json /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.* 7 | .yarn/* 8 | !.yarn/patches 9 | !.yarn/plugins 10 | !.yarn/releases 11 | !.yarn/versions 12 | 13 | # testing 14 | /coverage 15 | 16 | # next.js 17 | /.next/ 18 | /out/ 19 | 20 | # production 21 | /build 22 | 23 | # misc 24 | .DS_Store 25 | *.pem 26 | 27 | # debug 28 | npm-debug.log* 29 | yarn-debug.log* 30 | yarn-error.log* 31 | .pnpm-debug.log* 32 | 33 | # env files (can opt-in for committing if needed) 34 | .env 35 | 36 | # vercel 37 | .vercel 38 | 39 | # typescript 40 | *.tsbuildinfo 41 | next-env.d.ts 42 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Just a basic random text generator 2 | -------------------------------------------------------------------------------- /app/api/generate/route.tsx: -------------------------------------------------------------------------------- 1 | // app/api/generate/route.ts 2 | import { NextRequest, NextResponse } from 'next/server'; 3 | 4 | interface RequestBody { 5 | text: string; 6 | wordCount: number; 7 | } 8 | 9 | interface HuggingFaceResponse { 10 | generated_text: string; 11 | } 12 | 13 | interface ErrorResponse { 14 | error: string; 15 | } 16 | 17 | export async function POST(req: NextRequest): Promise> { 18 | try { 19 | const body = await req.json(); 20 | const { text, wordCount } = body as RequestBody; 21 | 22 | if (!text) { 23 | return NextResponse.json( 24 | { error: 'Text field is required' }, 25 | { status: 400 } 26 | ); 27 | } 28 | 29 | const validatedWordCount = Math.min(Math.max(Number(wordCount) || 100, 50), 5000); 30 | 31 | const apiKey = process.env.NEXT_PUBLIC_HUGGING_FACE_API_KEY; 32 | if (!apiKey) { 33 | throw new Error('Hugging Face API key is not configured'); 34 | } 35 | 36 | const response = await fetch( 37 | "https://api-inference.huggingface.co/models/gpt2", 38 | { 39 | headers: { 40 | "Authorization": `Bearer ${apiKey}`, 41 | "Content-Type": "application/json", 42 | }, 43 | method: "POST", 44 | body: JSON.stringify({ 45 | inputs: text, 46 | parameters: { 47 | max_new_tokens: Math.floor(validatedWordCount * 1.5), 48 | return_full_text: false, 49 | do_sample: true, 50 | temperature: 0.7, 51 | top_p: 0.95, 52 | } 53 | }), 54 | } 55 | ); 56 | 57 | if (!response.ok) { 58 | throw new Error(`API call failed with status: ${response.status}`); 59 | } 60 | 61 | const data = await response.json(); 62 | // Return the first result directly as an object, not an array 63 | return NextResponse.json({ 64 | generated_text: data[0].generated_text 65 | }); 66 | 67 | } catch (error) { 68 | const errorMessage = error instanceof Error ? error.message : 'An unknown error occurred'; 69 | return NextResponse.json( 70 | { error: errorMessage }, 71 | { status: 500 } 72 | ); 73 | } 74 | } -------------------------------------------------------------------------------- /app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MainakVerse/random-text-generator/9caa5e90c362071bbf83d9092f46245a7c376e21/app/favicon.ico -------------------------------------------------------------------------------- /app/globals.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | body { 6 | font-family: Arial, Helvetica, sans-serif; 7 | } 8 | 9 | @layer base { 10 | :root { 11 | --radius: 0.5rem; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /app/layout.tsx: -------------------------------------------------------------------------------- 1 | import type { Metadata } from "next"; 2 | import { Geist, Geist_Mono } from "next/font/google"; 3 | import "./globals.css"; 4 | 5 | const geistSans = Geist({ 6 | variable: "--font-geist-sans", 7 | subsets: ["latin"], 8 | }); 9 | 10 | const geistMono = Geist_Mono({ 11 | variable: "--font-geist-mono", 12 | subsets: ["latin"], 13 | }); 14 | 15 | export const metadata: Metadata = { 16 | title: "Random Text Generator", 17 | description: "Generated with Hugging Face TextGen API for testing", 18 | }; 19 | 20 | export default function RootLayout({ 21 | children, 22 | }: Readonly<{ 23 | children: React.ReactNode; 24 | }>) { 25 | return ( 26 | 27 | 30 | {children} 31 | 32 | 33 | ); 34 | } 35 | -------------------------------------------------------------------------------- /app/page.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import { useState } from 'react'; 4 | 5 | export default function Home() { 6 | const [input, setInput] = useState(''); 7 | const [result, setResult] = useState(''); 8 | const [loading, setLoading] = useState(false); 9 | const [wordCount, setWordCount] = useState(500); 10 | 11 | const generateText = async () => { 12 | try { 13 | setLoading(true); 14 | const response = await fetch('/api/generate', { 15 | method: 'POST', 16 | headers: { 17 | 'Content-Type': 'application/json', 18 | }, 19 | body: JSON.stringify({ 20 | text: input, 21 | wordCount: wordCount 22 | }), 23 | }); 24 | 25 | const data = await response.json(); 26 | // Handle the response data directly without array access 27 | setResult(data.generated_text); 28 | } catch (error) { 29 | console.error('Error:', error); 30 | setResult('Error generating text'); 31 | } finally { 32 | setLoading(false); 33 | } 34 | }; 35 | 36 | const getBackgroundSize = () => { 37 | return { 38 | backgroundSize: `${((wordCount - 50) * 100) / (5000 - 50)}% 100%` 39 | }; 40 | }; 41 | 42 | return ( 43 |
44 | 98 | 99 |
100 |

101 | Random Text Generator 102 |

103 | 104 |
105 |
106 | Word Count: {wordCount} 107 | {wordCount} words 108 |
109 | setWordCount(Number(e.target.value))} 116 | className="w-full" 117 | style={getBackgroundSize()} 118 | /> 119 |
120 | 50 121 | 5000 122 |
123 |
124 | 125 |