Skip to content

Commit da5e64a

Browse files
authored
Merge pull request #69 from DMU-DebugVisual/sojeong
코드방송 IDE 라이브러리 연결 및 UI 수정
2 parents 1ed7849 + 8a2e396 commit da5e64a

File tree

10 files changed

+109
-87
lines changed

10 files changed

+109
-87
lines changed

src/App.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import ScrollToTop from "./components/common/ScrollToTop";
2020
import CommunityWrite from "./components/community/CommunityWrite";
2121
import VisualizationModal from "./components/ide/VisualizationModal";
2222
import PostDetail from "./components/community/PostDetail"; // ✅ 게시글 상세 컴포넌트 추가
23+
import CodecastLive from "./components/codecast/codecastlive/CodecastLive";
2324

2425
function AppContent() {
2526
const location = useLocation();
@@ -77,6 +78,7 @@ function AppContent() {
7778
<Route path="/community/post/:id" element={<PostDetail />} /> {/* ✅ 상세 페이지 라우팅 추가 */}
7879
<Route path="/broadcast" element={<Codecast />} />
7980
<Route path="/startbroadcast" element={<StartCodecast />} />
81+
<Route path="/broadcast/live" element={<CodecastLive />} />
8082
<Route path="/mypage" element={<MyPageLayout nickname={nickname} />}>
8183
<Route index element={<Mypage nickname={nickname} />} />
8284
<Route path="project" element={<MyProject />} />

src/components/codecast/codecastlive/CodeEditor.jsx

Lines changed: 34 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,54 @@
1-
import React from 'react';
2-
import './CodeEditor.css';
1+
import React, {useEffect, useState} from 'react';
2+
import Editor from '@monaco-editor/react';
33
import { FaPlay } from 'react-icons/fa';
4+
import './CodeEditor.css';
45

5-
const currentUser = {
6-
name: '김코딩',
7-
role: 'host',
8-
code: `# 버블 정렬 구현
9-
def bubble_sort(arr):
10-
n = len(arr)
11-
12-
for i in range(n):
13-
for j in range(0, n - i - 1):
14-
if arr[j] > arr[j + 1]:
15-
# 두 요소 교환
16-
arr[j], arr[j + 1] = arr[j + 1], arr[j]
17-
18-
return arr
19-
20-
# 예제 배열
21-
array = [64, 34, 25, 12, 22, 11, 90]
22-
print("정렬 전:", array)
23-
print("정렬 후:", bubble_sort(array.copy()))`
24-
};
6+
const CodeEditor = ({ currentUser }) => {
7+
const [code, setCode] = useState(currentUser.code);
258

26-
const getIcon = (role) => {
27-
switch (role) {
28-
case 'host':
29-
return '👑';
30-
case 'editing':
31-
return '✍️';
32-
default:
33-
return '';
34-
}
35-
};
9+
// ✅ currentUser가 바뀔 때마다 코드 상태를 새로 설정
10+
useEffect(() => {
11+
setCode(currentUser.code);
12+
}, [currentUser]);
3613

37-
const CodeEditor = () => {
3814
const handleRun = () => {
3915
alert("코드 실행 기능은 아직 미구현입니다.");
4016
};
4117

18+
const getIcon = (role) => {
19+
switch (role) {
20+
case 'host':
21+
return '👑';
22+
case 'editing':
23+
return '✍️';
24+
default:
25+
return '';
26+
}
27+
};
28+
4229
return (
4330
<section className="code-editor">
4431
<div className="editor-header">
4532
<div className="current-user-badge">
4633
{getIcon(currentUser.role)} {currentUser.name}
4734
</div>
4835
<button className="run-button" onClick={handleRun}>
49-
<FaPlay/> 실행
36+
<FaPlay /> 실행
5037
</button>
5138
</div>
52-
<pre className="code-block">
53-
<code>{currentUser.code}</code>
54-
</pre>
39+
40+
<Editor
41+
height="calc(100vh - 160px)" // 헤더와 버튼 고려
42+
defaultLanguage="python"
43+
theme="vs-dark"
44+
value={code}
45+
onChange={(newValue) => setCode(newValue)}
46+
options={{
47+
fontSize: 14,
48+
minimap: { enabled: false },
49+
padding: { top: 10 },
50+
}}
51+
/>
5552
</section>
5653
);
5754
};

src/components/codecast/codecastlive/CodePreviewList.css

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,10 @@
4242
font-size: 16px;
4343
}
4444

45-
.preview-language {
46-
font-size: 12px;
47-
color: #aaa;
48-
margin-bottom: 8px;
49-
}
50-
5145
.preview-code {
5246
padding: 12px;
5347
white-space: pre-wrap;
5448
line-height: 1.5;
49+
max-height: calc(1.4em * 5); /* 4줄 기준 */
50+
overflow: hidden;
5551
}

src/components/codecast/codecastlive/CodePreviewList.jsx

Lines changed: 9 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,20 @@
11
import React from 'react';
22
import './CodePreviewList.css';
33

4-
const previews = [
5-
{
6-
name: '김코딩',
7-
// language: 'Python',
8-
code: `# 버블 정렬 구현\ndef bubble_sort(arr):\n n = len(arr)\n`,
9-
isHost: true
10-
},
11-
{
12-
name: '이알고',
13-
// language: 'JavaScript',
14-
code: `// 퀵 정렬 구현\nfunction quickSort(arr) {\n if (arr.length <= 1) {\n return arr;`,
15-
isHost: false
16-
},
17-
{
18-
name: '박개발',
19-
// language: 'JavaScript',
20-
code: `// 병합 정렬 구현\nfunction mergeSort(arr) {\n if (arr.length <= 1) {\n return arr;`,
21-
isHost: false
22-
}
23-
];
24-
25-
const CodePreviewList = () => {
4+
const CodePreviewList = ({ participants, onSelect }) => {
265
return (
276
<section className="code-preview-list">
28-
{previews.map((p, idx) => (
29-
<div key={idx} className="code-preview-card">
7+
{participants.map((p, idx) => (
8+
<div
9+
key={idx}
10+
className="code-preview-card"
11+
onClick={() => onSelect(p)}
12+
style={{ cursor: 'pointer' }}
13+
>
3014
<div className="card-header">
3115
<span className="card-name">{p.name}</span>
32-
{p.isHost && <span className="card-role">👑</span>}
16+
{p.role === 'host' && <span className="card-role">👑</span>}
3317
</div>
34-
{/*<div className="preview-language">{p.language}</div>*/}
3518
<pre className="preview-code">{p.code}</pre>
3619
</div>
3720
))}

src/components/codecast/codecastlive/CodecastHeader.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
.broadcast-header {
1+
.broadcastlive-header {
22
display: flex;
33
justify-content: space-between;
44
align-items: center;

src/components/codecast/codecastlive/CodecastHeader.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ const CodecastHeader = () => {
88
};
99

1010
return (
11-
<header className="broadcast-header">
11+
<header className="broadcastlive-header">
1212
<div className="header-left">
1313
<h1 className="broadcast-title">정렬 알고리즘 라이브 코딩</h1>
1414
</div>

src/components/codecast/codecastlive/CodecastLive.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
height: 100vh;
55
background-color: #111;
66
color: white;
7+
padding-top: 70px;
78
}
89

910
.main-section {
Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,63 @@
1-
import React from 'react';
1+
import React, { useState } from 'react';
22
import './CodecastLive.css';
33

44
import Header from './CodecastHeader';
55
import Sidebar from './CodecastSidebar';
66
import CodeEditor from './CodeEditor';
77
import CodePreviewList from './CodePreviewList';
88

9-
const CodeBroadcastPage = () => {
9+
const participants = [
10+
{
11+
name: '김코딩',
12+
code: `# 버블 정렬 구현
13+
def bubble_sort(arr):
14+
n = len(arr)
15+
16+
for i in range(n):
17+
for j in range(0, n - i - 1):
18+
if arr[j] > arr[j + 1]:
19+
# 두 요소 교환
20+
arr[j], arr[j + 1] = arr[j + 1], arr[j]
21+
22+
return arr
23+
24+
# 예제 배열
25+
array = [64, 34, 25, 12, 22, 11, 90]
26+
print("정렬 전:", array)
27+
print("정렬 후:", bubble_sort(array.copy()))`,
28+
role: 'host'
29+
},
30+
{
31+
name: '이알고',
32+
code: `// 퀵 정렬 구현\nfunction quickSort(arr) {\n if (arr.length <= 1) {\n return arr;`,
33+
role: 'editing'
34+
},
35+
{
36+
name: '박개발',
37+
code: `// 병합 정렬 구현\nfunction mergeSort(arr) {\n if (arr.length <= 1) {\n return arr;`,
38+
role: 'editing'
39+
}
40+
];
41+
42+
const CodecastLive = () => {
43+
const [currentUser, setCurrentUser] = useState(participants[0]);
44+
1045
return (
1146
<div className="broadcast-wrapper">
1247
<Header />
1348
<div className="main-section">
14-
<Sidebar />
15-
<CodeEditor />
49+
<Sidebar
50+
participants={participants}
51+
currentUser={currentUser}
52+
/>
53+
<CodeEditor currentUser={currentUser} />
1654
</div>
17-
<CodePreviewList />
55+
<CodePreviewList
56+
participants={participants}
57+
onSelect={(user) => setCurrentUser(user)}
58+
/>
1859
</div>
1960
);
2061
};
2162

22-
export default CodeBroadcastPage;
63+
export default CodecastLive;

src/components/codecast/codecastlive/CodecastSidebar.css

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
.sidebar-title {
1010
font-size: 16px;
1111
margin-bottom: 12px;
12+
color: white;
1213
}
1314

1415
.participant-list {
@@ -40,3 +41,9 @@
4041
.participant-icon.gray {
4142
color: #777;
4243
}
44+
45+
.participant-item.active-user {
46+
background-color: #2a2a2a;
47+
/*border-left: 4px solid #6a0dad;*/
48+
font-weight: bold;
49+
}

src/components/codecast/codecastlive/CodecastSidebar.jsx

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,6 @@ import React from 'react';
22
import './CodecastSidebar.css';
33
import { FaCrown, FaPenFancy, FaCircle } from 'react-icons/fa';
44

5-
const participants = [
6-
{ name: '김코딩', role: 'host' },
7-
{ name: '이알고', role: 'editing' },
8-
{ name: '박개발', role: 'editing' },
9-
{ name: '최자료', role: 'viewer' },
10-
{ name: '정해시', role: 'viewer' }
11-
];
12-
135
const getIcon = (role) => {
146
switch (role) {
157
case 'host':
@@ -21,13 +13,16 @@ const getIcon = (role) => {
2113
}
2214
};
2315

24-
const CodecastSidebar = () => {
16+
const CodecastSidebar = ({ participants, currentUser }) => {
2517
return (
2618
<aside className="sidebar">
2719
<h2 className="sidebar-title">참여자 ({participants.length})</h2>
2820
<ul className="participant-list">
2921
{participants.map((p, idx) => (
30-
<li key={idx} className="participant-item">
22+
<li
23+
key={idx}
24+
className={`participant-item ${p.name === currentUser.name ? 'active-user' : ''}`}
25+
>
3126
{getIcon(p.role)}
3227
<span>{p.name}</span>
3328
</li>

0 commit comments

Comments
 (0)