@@ -12,8 +12,9 @@ import {
1212 SelectTrigger ,
1313 SelectValue ,
1414} from "@/components/ui/select" ;
15- import { Check , Info , Loader2 , Save , Eye , EyeOff } from "lucide-react" ;
15+ import { Check , Info , Loader2 , Save , Eye , EyeOff , Wand2 } from "lucide-react" ;
1616import { useTranslation } from "next-i18next" ;
17+ import { generateAIName } from "@/utils/aiName" ;
1718
1819const DEFAULT_LANGUAGE = "html" ;
1920
@@ -58,6 +59,8 @@ const CodeEditor = ({
5859 const [ isLoading , setIsLoading ] = useState ( false ) ;
5960 const [ darkMode , setDarkMode ] = useState ( true ) ;
6061 const [ editorWidth , setEditorWidth ] = useState ( "100%" ) ;
62+ const [ isGeneratingName , setIsGeneratingName ] = useState ( false ) ;
63+ const nameGeneratorRef = useRef ( new AbortController ( ) ) ;
6164 const containerRef = useRef ( null ) ;
6265
6366 const updateDefaultLanguage = ( newLanguage : string ) => {
@@ -113,6 +116,12 @@ const CodeEditor = ({
113116 } ;
114117 } , [ ] ) ;
115118
119+ useEffect ( ( ) => {
120+ if ( nameGeneratorRef . current ) {
121+ nameGeneratorRef . current . abort ( ) ;
122+ }
123+ } , [ code ] ) ;
124+
116125 const handleSave = async ( ) => {
117126 setIsSaving ( true ) ;
118127 setSaveSuccess ( "Saving..." ) ;
@@ -148,19 +157,57 @@ const CodeEditor = ({
148157 }
149158 } ;
150159
160+ const ai_nameProject = async ( ) => {
161+ if ( nameGeneratorRef . current ) {
162+ nameGeneratorRef . current . abort ( ) ;
163+ }
164+ nameGeneratorRef . current = new AbortController ( ) ;
165+ setIsGeneratingName ( true ) ;
166+
167+ try {
168+ const name = await generateAIName ( code , nameGeneratorRef . current . signal ) ;
169+ setName ( name ) ;
170+ } catch ( error : any ) {
171+ if ( error . name === "AbortError" ) {
172+ console . log ( "Request was aborted" ) ;
173+ } else {
174+ console . error ( "Failed to generate AI name:" , error ) ;
175+ }
176+ } finally {
177+ setIsGeneratingName ( false ) ;
178+ }
179+
180+ return ( ) => {
181+ nameGeneratorRef . current . abort ( ) ; // Cancel the request if needed
182+ } ;
183+ } ;
184+
151185 return (
152186 < div className = "flex flex-col h-full w-full" >
153187 < div className = "flex justify-between items-center p-4 bg-gray-200 text-black dark:bg-gray-800 dark:text-white" >
154188 < div className = "flex items-center flex-row gap-4 w-1/2" >
155- < Input
156- type = "text"
157- placeholder = { t ( "project-name" ) }
158- value = { name }
159- minLength = { 2 }
160- onChange = { ( e ) => setName ( e . target . value ) }
161- className = "p-2 border rounded w-24 sm:w-32 md:w-48 lg:w-64 xl:w-72 text-black dark:bg-gray-800 dark:text-white dark:border-gray-700"
162- disabled = { isLoading }
163- />
189+ < div className = "relative" >
190+ < Input
191+ type = "text"
192+ placeholder = { t ( "project-name" ) }
193+ value = { name }
194+ minLength = { 2 }
195+ onChange = { ( e ) => setName ( e . target . value ) }
196+ className = "p-2 pr-10 border rounded w-full text-black dark:bg-gray-800 dark:text-white dark:border-gray-700"
197+ disabled = { isLoading }
198+ />
199+ < Button
200+ onClick = { ai_nameProject }
201+ disabled = { isSaving || isLoading }
202+ className = "absolute w-6 h-6 p-1 right-2 top-1/2 transform -translate-y-1/2"
203+ >
204+ { isGeneratingName ? (
205+ < Loader2 className = "w-4 h-4 animate-spin" />
206+ ) : (
207+ < Wand2 className = "w-4 h-4" />
208+ ) }
209+ </ Button >
210+ </ div >
164211 < Select
165212 value = { language }
166213 onValueChange = { ( value ) => setLanguage ( value ) }
0 commit comments