@@ -586,77 +586,127 @@ const IDE = () => {
586586 }
587587 } ;
588588
589- // 🆕 개선된 시각화 클릭 핸들러
590- const handleVisualizationClick = async ( ) => {
591- if ( ! code . trim ( ) ) {
592- alert ( '시각화할 코드를 먼저 작성해주세요.' ) ;
593- return ;
594- }
595589
596- const fileType = getFileType ( fileName ) ;
597- setCurrentFileType ( fileType ) ;
598590
599- if ( fileType === 'json' ) {
600- // JSON 파일인 경우: API 호출 없이 에디터 내용을 직접 파싱
601- console . log ( '📄 JSON 파일 시각화 - API 호출 없음' ) ;
602- try {
603- const jsonData = JSON . parse ( code ) ;
604- setSelectedJsonData ( jsonData ) ;
605- setIsExampleFile ( false ) ;
606- setIsVisualizationModalOpen ( true ) ;
607- } catch ( error ) {
608- alert ( `JSON 형식이 올바르지 않습니다: ${ error . message } ` ) ;
609- return ;
610- }
591+ // 🆕 개선된 시각화 클릭 핸들러 (AST 부분만 저장)
592+ // IDE.jsx의 handleVisualizationClick 함수에서 수정할 부분
593+
594+ // 🆕 개선된 시각화 클릭 핸들러 (AST 부분만 저장)
595+ // 🆕 JSON 파일 생성/업데이트 함수 (문자열 그대로 저장)
596+ const createOrUpdateJsonFileRaw = async ( jsonFileName , content ) => {
597+ try {
598+ // savedFiles에서 기존 JSON 파일 찾기
599+ const existingFileIndex = savedFiles . findIndex ( f => f . name === jsonFileName ) ;
600+
601+ if ( existingFileIndex >= 0 ) {
602+ // 기존 파일 업데이트
603+ const updatedFiles = [ ...savedFiles ] ;
604+ updatedFiles [ existingFileIndex ] = {
605+ name : jsonFileName ,
606+ code : content , // JSON.stringify 없이 직접 저장
607+ type : 'json'
608+ } ;
609+ setSavedFiles ( updatedFiles ) ;
610+ console . log ( `✅ JSON 파일 업데이트됨: ${ jsonFileName } ` ) ;
611611 } else {
612- // 코드 파일인 경우: API 호출 후 JSON 파일 생성/덮어쓰기
613- console . log ( '💻 코드 파일 시각화 - API 호출 후 JSON 생성' ) ;
612+ // 새 JSON 파일 생성
613+ const newJsonFile = {
614+ name : jsonFileName ,
615+ code : content , // JSON.stringify 없이 직접 저장
616+ type : 'json'
617+ } ;
618+ setSavedFiles ( prev => [ ...prev , newJsonFile ] ) ;
619+ console . log ( `✅ JSON 파일 생성됨: ${ jsonFileName } ` ) ;
620+ }
614621
615- try {
616- // API 호출
617- const apiUrl = config . API_ENDPOINTS . VISUALIZE_CODE || `${ config . API_BASE_URL } /visualize` ;
618- const requestBody = {
619- code : code ,
620- input : input ,
621- lang : mapLanguageToAPI ( selectedLanguage )
622- } ;
622+ return content ;
623+ } catch ( error ) {
624+ console . error ( '❌ JSON 파일 생성/업데이트 실패:' , error ) ;
625+ throw error ;
626+ }
627+ } ;
623628
624- console . log ( '🚀 시각화 API 호출:' , requestBody ) ;
629+ // 🆕 개선된 시각화 클릭 핸들러 (AST 부분만 저장)
630+ const handleVisualizationClick = async ( ) => {
631+ if ( ! code . trim ( ) ) {
632+ alert ( '시각화할 코드를 먼저 작성해주세요.' ) ;
633+ return ;
634+ }
625635
626- const response = await fetch ( apiUrl , {
627- method : 'POST' ,
628- headers : {
629- 'Content-Type' : 'application/json' ,
630- } ,
631- body : JSON . stringify ( requestBody ) ,
632- } ) ;
636+ const fileType = getFileType ( fileName ) ;
637+ setCurrentFileType ( fileType ) ;
633638
634- if ( ! response . ok ) {
635- throw new Error ( `API 요청 실패: ${ response . status } ${ response . statusText } ` ) ;
636- }
639+ if ( fileType === 'json' ) {
640+ // JSON 파일인 경우: API 호출 없이 에디터 내용을 직접 파싱
641+ console . log ( '📄 JSON 파일 시각화 - API 호출 없음' ) ;
642+ try {
643+ const jsonData = JSON . parse ( code ) ;
644+ setSelectedJsonData ( jsonData ) ;
645+ setIsExampleFile ( false ) ;
646+ setIsVisualizationModalOpen ( true ) ;
647+ } catch ( error ) {
648+ alert ( `JSON 형식이 올바르지 않습니다: ${ error . message } ` ) ;
649+ return ;
650+ }
651+ } else {
652+ // 코드 파일인 경우: API 호출 후 AST 부분만 JSON 파일로 생성/덮어쓰기
653+ console . log ( '💻 코드 파일 시각화 - API 호출 후 AST만 JSON 생성' ) ;
637654
638- const visualizationData = await response . json ( ) ;
639- console . log ( '✅ 시각화 데이터 수신:' , visualizationData ) ;
655+ try {
656+ // API 호출
657+ const apiUrl = config . API_ENDPOINTS . VISUALIZE_CODE || `${ config . API_BASE_URL } /visualize` ;
658+ const requestBody = {
659+ code : code ,
660+ input : input ,
661+ lang : mapLanguageToAPI ( selectedLanguage )
662+ } ;
640663
641- // 매칭되는 JSON 파일명 생성
642- const jsonFileName = getMatchingJsonFileName ( fileName ) ;
664+ console . log ( '🚀 시각화 API 호출:' , requestBody ) ;
643665
644- // JSON 파일 생성/업데이트
645- await createOrUpdateJsonFile ( jsonFileName , visualizationData ) ;
666+ const response = await fetch ( `${ config . API_BASE_URL } /api/code/visualize` , {
667+ method : 'POST' ,
668+ headers : {
669+ 'Content-Type' : 'application/json' ,
670+ } ,
671+ body : JSON . stringify ( requestBody ) ,
672+ } ) ;
646673
647- // 시각화 모달 열기
648- setSelectedJsonData ( visualizationData ) ;
649- setIsExampleFile ( false ) ;
650- setIsVisualizationModalOpen ( true ) ;
674+ if ( ! response . ok ) {
675+ throw new Error ( `API 요청 실패: ${ response . status } ${ response . statusText } ` ) ;
676+ }
651677
652- toast ( `시각화 완료! ${ jsonFileName } 파일이 생성/업데이트되었습니다.` ) ;
678+ const apiResponse = await response . json ( ) ;
679+ console . log ( '✅ API 응답 수신:' , apiResponse ) ;
653680
654- } catch ( error ) {
655- console . error ( '❌ 시각화 실패:' , error ) ;
656- alert ( `시각화 실패: ${ error . message } ` ) ;
681+ // 🔥 핵심 변경: AST 부분만 추출 (API에서 온 따옴표 제거)
682+ let visualizationData = apiResponse . ast || "AST 데이터가 없습니다." ;
683+
684+ // API에서 온 양 끝 따옴표 제거
685+ if ( typeof visualizationData === 'string' && visualizationData . startsWith ( '"' ) && visualizationData . endsWith ( '"' ) ) {
686+ visualizationData = visualizationData . slice ( 1 , - 1 ) ;
657687 }
688+
689+ console . log ( '📊 AST 데이터 추출 (따옴표 제거 후):' , visualizationData ) ;
690+
691+ // 매칭되는 JSON 파일명 생성
692+ const jsonFileName = getMatchingJsonFileName ( fileName ) ;
693+
694+ // AST 데이터를 JSON 파일로 생성/업데이트 (JSON.stringify 없이 직접 저장)
695+ await createOrUpdateJsonFileRaw ( jsonFileName , visualizationData ) ;
696+
697+ // 시각화 모달 열기
698+ setSelectedJsonData ( visualizationData ) ;
699+ setIsExampleFile ( false ) ;
700+ setIsVisualizationModalOpen ( true ) ;
701+
702+ toast ( `시각화 완료! ${ jsonFileName } 파일이 생성/업데이트되었습니다.` ) ;
703+
704+ } catch ( error ) {
705+ console . error ( '❌ 시각화 실패:' , error ) ;
706+ alert ( `시각화 실패: ${ error . message } ` ) ;
658707 }
659- } ;
708+ }
709+ } ;
660710
661711 // 🆕 개선된 파일 선택 핸들러
662712 const handleFileSelect = ( name ) => {
0 commit comments