diff --git a/src/components/codecast/codecastlive/CodeEditor.css b/src/components/codecast/codecastlive/CodeEditor.css new file mode 100644 index 0000000..c61efc2 --- /dev/null +++ b/src/components/codecast/codecastlive/CodeEditor.css @@ -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; +} diff --git a/src/components/codecast/codecastlive/CodeEditor.jsx b/src/components/codecast/codecastlive/CodeEditor.jsx new file mode 100644 index 0000000..1173a81 --- /dev/null +++ b/src/components/codecast/codecastlive/CodeEditor.jsx @@ -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 ( +
+
+
+ {getIcon(currentUser.role)} {currentUser.name} +
+ +
+
+                {currentUser.code}
+            
+
+ ); +}; + +export default CodeEditor; diff --git a/src/components/codecast/codecastlive/CodePreviewList.css b/src/components/codecast/codecastlive/CodePreviewList.css new file mode 100644 index 0000000..705fef9 --- /dev/null +++ b/src/components/codecast/codecastlive/CodePreviewList.css @@ -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; +} diff --git a/src/components/codecast/codecastlive/CodePreviewList.jsx b/src/components/codecast/codecastlive/CodePreviewList.jsx new file mode 100644 index 0000000..89f0ebf --- /dev/null +++ b/src/components/codecast/codecastlive/CodePreviewList.jsx @@ -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 ( +
+ {previews.map((p, idx) => ( +
+
+ {p.name} + {p.isHost && 👑} +
+ {/*
{p.language}
*/} +
{p.code}
+
+ ))} +
+ ); +}; + +export default CodePreviewList; diff --git a/src/components/codecast/codecastlive/CodecastHeader.css b/src/components/codecast/codecastlive/CodecastHeader.css new file mode 100644 index 0000000..6db5a66 --- /dev/null +++ b/src/components/codecast/codecastlive/CodecastHeader.css @@ -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; +} diff --git a/src/components/codecast/codecastlive/CodecastHeader.jsx b/src/components/codecast/codecastlive/CodecastHeader.jsx new file mode 100644 index 0000000..1e83768 --- /dev/null +++ b/src/components/codecast/codecastlive/CodecastHeader.jsx @@ -0,0 +1,26 @@ +import React from 'react'; +import './CodecastHeader.css'; + +const CodecastHeader = () => { + const handleExit = () => { + // 실제 방송 종료 처리 로직이 들어갈 수 있음 + alert('방송을 종료하고 나갑니다.'); + }; + + return ( +
+
+

정렬 알고리즘 라이브 코딩

+
+ +
+ Python + +
+
+ ); +}; + +export default CodecastHeader; diff --git a/src/components/codecast/codecastlive/CodecastLive.css b/src/components/codecast/codecastlive/CodecastLive.css new file mode 100644 index 0000000..6947a70 --- /dev/null +++ b/src/components/codecast/codecastlive/CodecastLive.css @@ -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; +} diff --git a/src/components/codecast/codecastlive/CodecastLive.jsx b/src/components/codecast/codecastlive/CodecastLive.jsx new file mode 100644 index 0000000..a1a4d5c --- /dev/null +++ b/src/components/codecast/codecastlive/CodecastLive.jsx @@ -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 ( +
+
+
+ + +
+ +
+ ); +}; + +export default CodeBroadcastPage; diff --git a/src/components/codecast/codecastlive/CodecastSidebar.css b/src/components/codecast/codecastlive/CodecastSidebar.css new file mode 100644 index 0000000..017843a --- /dev/null +++ b/src/components/codecast/codecastlive/CodecastSidebar.css @@ -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; +} diff --git a/src/components/codecast/codecastlive/CodecastSidebar.jsx b/src/components/codecast/codecastlive/CodecastSidebar.jsx new file mode 100644 index 0000000..20c6645 --- /dev/null +++ b/src/components/codecast/codecastlive/CodecastSidebar.jsx @@ -0,0 +1,40 @@ +import React from 'react'; +import './CodecastSidebar.css'; +import { FaCrown, FaPenFancy, FaCircle } from 'react-icons/fa'; + +const participants = [ + { name: '김코딩', role: 'host' }, + { name: '이알고', role: 'editing' }, + { name: '박개발', role: 'editing' }, + { name: '최자료', role: 'viewer' }, + { name: '정해시', role: 'viewer' } +]; + +const getIcon = (role) => { + switch (role) { + case 'host': + return ; + case 'editing': + return ; + default: + return ; + } +}; + +const CodecastSidebar = () => { + return ( + + ); +}; + +export default CodecastSidebar;