Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions src/components/codecast/codecastlive/CodeEditor.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
.code-editor {
flex: 1;
display: flex;
flex-direction: column;
background-color: #0f0f1a;
padding: 20px;
overflow-y: auto;
color: white;
font-family: 'Courier New', monospace;
font-size: 15px;
}

.editor-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
}

.current-user-badge {
background-color: #222;
color: #fff;
padding: 6px 12px;
border-radius: 12px;
font-weight: 600;
font-size: 14px;
box-shadow: 0 0 4px rgba(0, 0, 0, 0.3);
}


.run-button {
background-color: #6a0dad;
color: white;
border: none;
padding: 6px 12px;
border-radius: 6px;
cursor: pointer;
font-size: 14px;
display: flex;
align-items: center;
gap: 6px;
transition: background-color 0.2s ease;
}

.run-button:hover {
background-color: #8844dd;
}

.code-block {
background-color: #0f0f1a;
padding: 10px;
white-space: pre-wrap;
line-height: 1.5;
}
59 changes: 59 additions & 0 deletions src/components/codecast/codecastlive/CodeEditor.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import React from 'react';
import './CodeEditor.css';
import { FaPlay } from 'react-icons/fa';

const currentUser = {
name: '김코딩',
role: 'host',
code: `# 버블 정렬 구현
def bubble_sort(arr):
n = len(arr)

for i in range(n):
for j in range(0, n - i - 1):
if arr[j] > arr[j + 1]:
# 두 요소 교환
arr[j], arr[j + 1] = arr[j + 1], arr[j]

return arr

# 예제 배열
array = [64, 34, 25, 12, 22, 11, 90]
print("정렬 전:", array)
print("정렬 후:", bubble_sort(array.copy()))`
};

const getIcon = (role) => {
switch (role) {
case 'host':
return '👑';
case 'editing':
return '✍️';
default:
return '';
}
};

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

return (
<section className="code-editor">
<div className="editor-header">
<div className="current-user-badge">
{getIcon(currentUser.role)} {currentUser.name}
</div>
<button className="run-button" onClick={handleRun}>
<FaPlay/> 실행
</button>
</div>
<pre className="code-block">
<code>{currentUser.code}</code>
</pre>
</section>
);
};

export default CodeEditor;
55 changes: 55 additions & 0 deletions src/components/codecast/codecastlive/CodePreviewList.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
.code-preview-list {
background-color: #191919;
padding: 12px 16px;
display: flex;
gap: 16px;
overflow-x: auto;
border-top: 1px solid #333;
}

.code-preview-card {
background-color: #1f1f2e;
border-radius: 10px;
min-width: 240px;
max-width: 240px;
flex-shrink: 0;
color: white;
font-size: 13px;
font-family: 'Courier New', monospace;
display: flex;
flex-direction: column;
border: 1px solid #333;
overflow: hidden;
}

.card-header {
background-color: #2c2c2c;
padding: 8px 12px;
display: flex;
justify-content: space-between;
align-items: center;
font-weight: bold;
font-size: 14px;
border-bottom: 1px solid #444;
height: 30px;
}

.card-name {
color: #fff;
}

.card-role {
font-size: 16px;
}

.preview-language {
font-size: 12px;
color: #aaa;
margin-bottom: 8px;
}

.preview-code {
padding: 12px;
white-space: pre-wrap;
line-height: 1.5;
}
42 changes: 42 additions & 0 deletions src/components/codecast/codecastlive/CodePreviewList.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import React from 'react';
import './CodePreviewList.css';

const previews = [
{
name: '김코딩',
// language: 'Python',
code: `# 버블 정렬 구현\ndef bubble_sort(arr):\n n = len(arr)\n`,
isHost: true
},
{
name: '이알고',
// language: 'JavaScript',
code: `// 퀵 정렬 구현\nfunction quickSort(arr) {\n if (arr.length <= 1) {\n return arr;`,
isHost: false
},
{
name: '박개발',
// language: 'JavaScript',
code: `// 병합 정렬 구현\nfunction mergeSort(arr) {\n if (arr.length <= 1) {\n return arr;`,
isHost: false
}
];

const CodePreviewList = () => {
return (
<section className="code-preview-list">
{previews.map((p, idx) => (
<div key={idx} className="code-preview-card">
<div className="card-header">
<span className="card-name">{p.name}</span>
{p.isHost && <span className="card-role">👑</span>}
</div>
{/*<div className="preview-language">{p.language}</div>*/}
<pre className="preview-code">{p.code}</pre>
</div>
))}
</section>
);
};

export default CodePreviewList;
51 changes: 51 additions & 0 deletions src/components/codecast/codecastlive/CodecastHeader.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
.broadcast-header {
display: flex;
justify-content: space-between;
align-items: center;
background-color: #1a1a1a;
padding: 16px 24px;
border-bottom: 1px solid #333;
color: white;
margin-bottom: 0;
}

.header-left {
display: flex;
align-items: center;
}

.broadcast-title {
font-size: 20px;
font-weight: bold;
margin: 0;
}

.header-right {
display: flex;
align-items: center;
gap: 12px;
}

.exit-button {
background-color: #333;
color: red;
border: none;
padding: 6px 12px;
border-radius: 6px;
cursor: pointer;
font-size: 14px;
transition: background-color 0.2s;
}

.exit-button:hover {
background-color: #555;
}

.language-tag {
background-color: #4b8bbe;
color: white;
font-size: 12px;
padding: 4px 10px;
border-radius: 20px;
font-weight: 500;
}
26 changes: 26 additions & 0 deletions src/components/codecast/codecastlive/CodecastHeader.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React from 'react';
import './CodecastHeader.css';

const CodecastHeader = () => {
const handleExit = () => {
// 실제 방송 종료 처리 로직이 들어갈 수 있음
alert('방송을 종료하고 나갑니다.');
};

return (
<header className="broadcast-header">
<div className="header-left">
<h1 className="broadcast-title">정렬 알고리즘 라이브 코딩</h1>
</div>

<div className="header-right">
<span className="language-tag">Python</span>
<button className="exit-button" onClick={handleExit}>
나가기
</button>
</div>
</header>
);
};

export default CodecastHeader;
13 changes: 13 additions & 0 deletions src/components/codecast/codecastlive/CodecastLive.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
.broadcast-wrapper {
display: flex;
flex-direction: column;
height: 100vh;
background-color: #111;
color: white;
}

.main-section {
flex: 1;
display: flex;
overflow: hidden;
}
22 changes: 22 additions & 0 deletions src/components/codecast/codecastlive/CodecastLive.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import React from 'react';
import './CodecastLive.css';

import Header from './CodecastHeader';
import Sidebar from './CodecastSidebar';
import CodeEditor from './CodeEditor';
import CodePreviewList from './CodePreviewList';

const CodeBroadcastPage = () => {
return (
<div className="broadcast-wrapper">
<Header />
<div className="main-section">
<Sidebar />
<CodeEditor />
</div>
<CodePreviewList />
</div>
);
};

export default CodeBroadcastPage;
42 changes: 42 additions & 0 deletions src/components/codecast/codecastlive/CodecastSidebar.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
.sidebar {
width: 200px;
background-color: #1c1c1c;
padding: 16px;
border-right: 1px solid #333;
color: white;
}

.sidebar-title {
font-size: 16px;
margin-bottom: 12px;
}

.participant-list {
list-style: none;
padding: 0;
margin: 0;
}

.participant-item {
display: flex;
align-items: center;
margin-bottom: 10px;
font-size: 14px;
gap: 8px;
}

.participant-icon {
font-size: 14px;
}

.participant-icon.gold {
color: gold;
}

.participant-icon.green {
color: #00c853;
}

.participant-icon.gray {
color: #777;
}
Loading