11"use client"
22
3- import { useState } from "react"
3+ import { useEffect , useState } from "react"
44import { Button } from "@/components/ui/button"
55import { Input } from "@/components/ui/input"
66import { Label } from "@/components/ui/label"
@@ -10,7 +10,12 @@ import { Download, Server, Globe } from "lucide-react"
1010import type { NodeDefinition } from "@/model/NodeDefinition"
1111import { Alert , AlertDescription , AlertTitle } from "@/components/ui/alert"
1212import { useTranslations } from "next-intl" ;
13- import { generateNodeJSFiles , generatePythonFiles , ProjectFile } from "@/utils/shop/project-generators" ;
13+ import {
14+ generateNextJsFiles ,
15+ generateNodeJSFiles ,
16+ generatePythonFiles ,
17+ ProjectFile
18+ } from "@/utils/shop/project-generators" ;
1419import { generateAndDownloadZip } from "@/utils/shop/zipUtils" ;
1520import { FileTree } from "@/components/shop/create-node/FileTree" ;
1621import { CodeEditor } from "@/components/shop/create-node/CodeEditor" ;
@@ -32,11 +37,12 @@ interface FileTreeItem {
3237export function StepServerConfig ( { nodeDefinition, updateNodeDefinition, onPrevious, onSave } : StepServerConfigProps ) {
3338 const t = useTranslations ( "shop.step-server-config" )
3439 const [ copied , setCopied ] = useState < string | null > ( null )
35- const [ selectedLanguage , setSelectedLanguage ] = useState ( " nodejs")
40+ const [ selectedLanguage , setSelectedLanguage ] = useState ( nodeDefinition . executionMode === "Automatic" ? " nodejs" : "nextjs ")
3641 const [ expandedFolders , setExpandedFolders ] = useState < Record < string , boolean > > ( {
3742 src : true ,
43+ app : true
3844 } )
39- const [ selectedFile , setSelectedFile ] = useState < string > ( " src/server.js")
45+ const [ selectedFile , setSelectedFile ] = useState < string > ( nodeDefinition . executionMode === "Automatic" ? " src/server.js" : "app/ExampleActivity.tsx ")
4046 const [ isDownloading , setIsDownloading ] = useState ( false )
4147
4248 const updateField = ( field : keyof NodeDefinition , value : string ) => {
@@ -64,8 +70,10 @@ export function StepServerConfig({ nodeDefinition, updateNodeDefinition, onPrevi
6470 case "python" :
6571 return generatePythonFiles ( nodeDefinition )
6672 case "nodejs" :
67- default :
6873 return generateNodeJSFiles ( nodeDefinition )
74+ case "nextjs" :
75+ default :
76+ return generateNextJsFiles ( nodeDefinition )
6977 }
7078 }
7179
@@ -76,8 +84,10 @@ export function StepServerConfig({ nodeDefinition, updateNodeDefinition, onPrevi
7684 // Set default selected file based on language
7785 if ( language === "python" ) {
7886 setSelectedFile ( "app.py" )
79- } else {
87+ } else if ( language === "nodejs" ) {
8088 setSelectedFile ( "src/server.js" )
89+ } else if ( language === "nextjs" ) {
90+ setSelectedFile ( "app/ExampleActivity.tsx" )
8191 }
8292 }
8393
@@ -170,6 +180,22 @@ export function StepServerConfig({ nodeDefinition, updateNodeDefinition, onPrevi
170180 }
171181
172182 const fileTree = buildFileTree ( projectFiles )
183+
184+ useEffect ( ( ) => {
185+ const path = nodeDefinition . executionUrl ? nodeDefinition . executionUrl ?. split ( "." ) [ 1 ] ?. split ( "/" ) . slice ( 1 ) . join ( "/" ) + "/" : ""
186+
187+ if ( path && path !== "/" ) {
188+ setExpandedFolders ( prev => ( {
189+ ...prev ,
190+ [ `app/${ path } ` . slice ( 0 , - 1 ) ] : true ,
191+ } ) )
192+ if ( selectedLanguage === "nextjs" && selectedFile . endsWith ( "ExampleActivity.tsx" ) ) {
193+ setSelectedFile ( `app/${ path } ExampleActivity.tsx` )
194+ }
195+ } else if ( selectedLanguage === "nextjs" && selectedFile . endsWith ( "ExampleActivity.tsx" ) ) {
196+ setSelectedFile ( "app/ExampleActivity.tsx" )
197+ }
198+ } , [ nodeDefinition . executionUrl , selectedFile , selectedLanguage ] )
173199
174200 return (
175201 < div className = "space-y-8" >
@@ -230,8 +256,9 @@ export function StepServerConfig({ nodeDefinition, updateNodeDefinition, onPrevi
230256 < Tabs defaultValue = "nodejs" value = { selectedLanguage } onValueChange = { handleLanguageChange } className = "p-4" >
231257 < div className = "flex flex-row justify-between" >
232258 < TabsList className = "mb-4 grid grid-cols-2 w-[200px]" >
233- < TabsTrigger value = "nodejs" > Node.js</ TabsTrigger >
234- < TabsTrigger value = "python" > Python</ TabsTrigger >
259+ { nodeDefinition . executionMode === "Automatic" && < TabsTrigger value = "nodejs" > Node.js</ TabsTrigger > }
260+ { nodeDefinition . executionMode === "Automatic" && < TabsTrigger value = "python" > Python</ TabsTrigger > }
261+ { nodeDefinition . executionMode === "Manual" && < TabsTrigger value = "nextjs" > Next.js</ TabsTrigger > }
235262 </ TabsList >
236263 < Button variant = "outline" size = "sm" onClick = { downloadProject } disabled = { isDownloading } >
237264 < Download className = "h-4 w-4 mr-2" />
@@ -306,6 +333,40 @@ export function StepServerConfig({ nodeDefinition, updateNodeDefinition, onPrevi
306333 </ div >
307334 </ div >
308335 </ TabsContent >
336+
337+ < TabsContent value = "nextjs" className = "mt-0 space-y-4" >
338+ < div className = "border rounded-md overflow-hidden" >
339+ < div className = "grid grid-cols-12 h-[550px]" >
340+ { /* File tree */ }
341+ < div className = "col-span-3 border-r bg-muted/30" >
342+ < div className = "p-3 border-b bg-muted/50 font-medium text-sm" > { t ( "templates.project-files" ) } </ div >
343+ < FileTree
344+ items = { fileTree }
345+ expandedFolders = { expandedFolders }
346+ selectedFile = { selectedFile }
347+ onToggleFolder = { toggleFolder }
348+ onSelectFile = { setSelectedFile }
349+ />
350+ </ div >
351+
352+ { /* Code editor */ }
353+ < div className = "col-span-9" >
354+ < div className = "p-3 border-b bg-muted/50 font-medium text-sm flex justify-between items-center" >
355+ < span > { selectedFile } </ span >
356+ </ div >
357+ < div className = "h-[500px] overflow-y-auto" >
358+ < CodeEditor
359+ code = { getSelectedFileContent ( ) }
360+ language = { getSelectedFileLanguage ( ) }
361+ fileName = { selectedFile }
362+ onCopy = { copyToClipboard }
363+ copied = { copied }
364+ />
365+ </ div >
366+ </ div >
367+ </ div >
368+ </ div >
369+ </ TabsContent >
309370 </ Tabs >
310371 </ CardContent >
311372 </ Card >
0 commit comments