Skip to content

Commit 230c927

Browse files
authored
Merge pull request #58 from DMU-DebugVisual/inseong
시각화 모듈화
2 parents 3eea95d + 1a8b17e commit 230c927

File tree

3 files changed

+135
-61
lines changed

3 files changed

+135
-61
lines changed

src/components/ide/IDE.jsx

Lines changed: 106 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -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) => {

src/components/ide/VisualizationModal.jsx

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -593,6 +593,8 @@ const InfoPanel = ({ data, currentStep, totalSteps, animationType }) => {
593593
{[
594594
{ label: '알고리즘', value: data?.algorithm || 'Unknown' },
595595
{ label: '언어', value: data?.lang || 'Unknown' },
596+
{ label: '⏰ 시간복잡도', value: data?.TimeComplexity || 'O(?)', isComplexity: true, complexityType: 'time' },
597+
{ label: '💾 공간복잡도', value: data?.SpaceComplexity || 'O(?)', isComplexity: true, complexityType: 'space' },
596598
{ label: '입력값', value: data?.input || '없음' },
597599
{ label: '변수 개수', value: `${data?.variables?.length || 0}개` },
598600
{ label: '실행 단계', value: `${totalSteps}단계` },
@@ -603,17 +605,38 @@ const InfoPanel = ({ data, currentStep, totalSteps, animationType }) => {
603605
display: 'flex',
604606
justifyContent: 'space-between',
605607
padding: '6px 8px',
606-
background: '#f8fafc',
608+
background: item.isComplexity
609+
? (item.complexityType === 'time'
610+
? 'linear-gradient(135deg, #fef3c7, #fde68a)'
611+
: 'linear-gradient(135deg, #dbeafe, #bfdbfe)')
612+
: '#f8fafc',
607613
borderRadius: '6px',
608-
fontSize: '12px'
614+
fontSize: '12px',
615+
border: item.isComplexity
616+
? (item.complexityType === 'time' ? '1px solid #f59e0b' : '1px solid #3b82f6')
617+
: 'none'
609618
}}>
610-
<span style={{ color: '#64748b' }}>{item.label}:</span>
611-
<span style={{ fontWeight: '600', color: '#1e293b' }}>{item.value}</span>
619+
<span style={{
620+
color: item.isComplexity
621+
? (item.complexityType === 'time' ? '#92400e' : '#1e40af')
622+
: '#64748b',
623+
fontWeight: item.isComplexity ? '600' : 'normal'
624+
}}>
625+
{item.label}:
626+
</span>
627+
<span style={{
628+
fontWeight: '600',
629+
color: item.isComplexity
630+
? (item.complexityType === 'time' ? '#92400e' : '#1e40af')
631+
: '#1e293b',
632+
fontFamily: item.isComplexity ? 'monospace' : 'inherit'
633+
}}>
634+
{item.value}
635+
</span>
612636
</div>
613637
))}
614638
</div>
615639
</InfoCard>
616-
617640
{/* API 출력 결과 */}
618641
{(data?.stdout || data?.stderr) && (
619642
<InfoCard title="실행 결과" icon="💻">

src/config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ const API_ENDPOINTS = {
55
LOGIN: `${API_BASE_URL}/api/auth/login`,
66
SIGNUP: `${API_BASE_URL}/api/auth/signup`,
77
RUN_CODE: `${API_BASE_URL}/api/code/run`,
8+
ISUALIZE_CODE: `${API_BASE_URL}/api/code/visualize`
89
// 필요시 다른 엔드포인트도 추가
910
};
1011

0 commit comments

Comments
 (0)