Skip to content
Open
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
129 changes: 101 additions & 28 deletions fe/src/page/MarkdownEditor.tsx
Original file line number Diff line number Diff line change
@@ -1,57 +1,98 @@
import React, { useState } from 'react';
import { ChangeEvent, useEffect, useState } from 'react';
import ReactMarkdown from 'react-markdown';
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
import { solarizedlight } from 'react-syntax-highlighter/dist/esm/styles/prism';

const MarkdownEditor = () => {
const [markdown, setMarkdown] = useState(`# 예시입니다
\`\`\`javascript
const hello = "안녕";
console.log(hello);
\`\`\`
`);
const [selectedLine, setSelectedLine] = useState(null);
const [markdown, setMarkdown] = useState('');
const [reviewMarkdown, setReviewMarkdown] = useState('');
const [selectedLine, setSelectedLine] = useState(-1);
const [editorContent, setEditorContent] = useState('');
// const [reviewEditorContent, setReviewEditorContent] = useState('');
const [originLines, setOriginLines] = useState<string[]>([]);
// const [changedLines, setChangedLines] = useState<number[]>([]);
const [isCodeRivew, setIsCodeReview] = useState(false);

const handleLineClick = (lineNumber) => {
const handleLineClick = (lineNumber: number) => {
console.log(`Clicked on line ${lineNumber}`);

// 현재 Markdown 텍스트에서 코드 블록을 추출하고 각 라인을 배열로 저장
const codeBlock = markdown.split('```')[1].trim();
const lines = codeBlock.split('\n');
setOriginLines(codeBlock.split('\n'));

// 선택된 라인 번호를 상태에 저장하여 나중에 사용할 수 있도록 함
setSelectedLine(lineNumber);
setEditorContent(lines[lineNumber]);

// 코드 라인을 클릭하면 code_review div를 보이도록 설정
setIsCodeReview(true);
};

useEffect(() => {
// selectedLine, originLines중 하나라도 변경될 때마다 실행
if (selectedLine !== -1) {
// 현재 선택된 라인에 해당하는 내용을 originLines 배열에서 가져와 editorContent 상태를 업데이트
setEditorContent(originLines[selectedLine]);
}
}, [selectedLine, originLines]);

// 에디터를 닫을 때 선택라인을 초기화
const handleEditorClose = () => {
setSelectedLine(null);
setSelectedLine(-1);
// 에디터를 닫을 때 code_review div를 숨기도록 설정
setIsCodeReview(false);
};

const handleEditorChange = (e) => {
// 에디터 콘텐츠를 현재 에디터의 내용으로 업데이트
const handleEditorChange = (e: ChangeEvent<HTMLTextAreaElement>) => {
setEditorContent(e.target.value);
// 리뷰 에디터 업데이트하기
// setReviewEditorContent(e.target.value);
};

const handleEditorSave = () => {
if (selectedLine === -1) return;
// 기존 코드 블록의 시작과 끝 위치를 찾음
const codeBlockStart = markdown.indexOf('```');
const codeBlockEnd = markdown.lastIndexOf('```');
// 코드 블록 앞과 뒤의 내용을 추출
const start = markdown.substring(0, codeBlockStart + 3);
const end = markdown.substring(codeBlockEnd);

// 코드 블록을 줄별로 분리하여 배열로 만듦
const lines = editorContent.split('\n');
const updatedCodeBlock = lines.map((line) => ` ${line}`).join('\n');
console.log(lines, updatedCodeBlock);
// 각 줄을 문자열로 가공
const updatedCodeBlock = lines.map((line) => `${line}`).join('\n');
// 기존 코드내용 복사하여, 수정된 코드 블록으로 업데이트
const copiedLines = [...originLines];
copiedLines[selectedLine] = updatedCodeBlock;

const reviewCodeBlock = '```' + `${copiedLines.join('\n')}\n` + '```';
// 기존 Markdown의 코드 블록 부분을 수정된 내용으로 업데이트
console.log(reviewCodeBlock);

setReviewMarkdown(reviewCodeBlock);

setMarkdown(`${start}\n${updatedCodeBlock}\n${end}`);
handleEditorClose();
};

return (
<div>
<textarea
id="origin-editor"
value={markdown}
onChange={(e) => setMarkdown(e.target.value)}
rows={10}
style={{ width: '100%' }}
style={{ width: '900px', height: '250px' }}
placeholder="사용자가 질문 작성시 사용할 입력창입니다"
/>
<div>
<textarea
id="review-editor"
value={reviewMarkdown}
onChange={(e) => setReviewMarkdown(e.target.value)}
rows={10}
style={{ width: '900px', height: '250px', display: 'none' }}
placeholder="나중에 사라질 녀석입니다"
/>
<div id="origin_code" style={{ width: '900px' }}>
<ReactMarkdown
components={{
code: ({ node, inline, className, children, ...props }) => {
Expand All @@ -61,7 +102,7 @@ const MarkdownEditor = () => {
style={solarizedlight}
language={match[1]}
PreTag="div"
children={String(children).replace(/\n$/, '')}
children={children.replace(/\n$/, '')}
showLineNumbers
wrapLines
lineProps={(lineNumber) => ({
Expand All @@ -76,7 +117,7 @@ const MarkdownEditor = () => {
/>
) : (
<code className={className} {...props}>
{children}
{markdown}
</code>
);
},
Expand All @@ -85,20 +126,52 @@ const MarkdownEditor = () => {
{markdown}
</ReactMarkdown>
</div>
{selectedLine !== null && (

<div id="review_code" style={{ width: '900px' }}>
<ReactMarkdown
components={{
code: ({ node, inline, className, children, ...props }) => {
const match = /language-(\w+)/.exec(className || '');
if (!inline && match) {
return (
<SyntaxHighlighter
style={solarizedlight}
language={match[1]}
PreTag="div"
children={String(children).replace(/\n$/, '')}
showLineNumbers
wrapLines
lineProps={(lineNumber) => ({})}
/>
);
}
return (
<code className={className} {...props}>
{children}
</code>
);
},
}}
>
{reviewMarkdown}
</ReactMarkdown>
</div>
{selectedLine && isCodeRivew !== null && (
<div>
<h4>Selected Line Editor</h4>
<button onClick={handleEditorClose}>Close Editor</button>

<textarea
value={editorContent}
onChange={handleEditorChange}
rows={3}
style={{ width: '100%' }}
style={{ width: '900px', height: '250px', display: 'block' }}
/>
<button onClick={handleEditorSave}>Save Changes</button>
<div>
<ReactMarkdown>{editorContent}</ReactMarkdown>
</div>
<button onClick={handleEditorClose} style={{ width: '70px', padding: '5px' }}>
닫기
</button>
<button onClick={handleEditorSave} style={{ width: '70px', padding: '5px' }}>
저장하기
</button>
</div>
)}
</div>
Expand Down
2 changes: 2 additions & 0 deletions fe/src/routes/router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import GridTemplate from '@components/layout/GridTemplate';
import Main from '@page/Main';
import RegisterEmail from '@page/RegisterEmail';
import AccountLinking from '@page/AccountLinking';
import MarkdownEditor from '@page/MarkdownEditor';

const Router = () => {
return (
Expand Down Expand Up @@ -37,6 +38,7 @@ const Router = () => {
{/* 나중에 Common 안에 넣어주기 */}
<Route path="/registeremail" element={<RegisterEmail />} />
<Route path="/accountlinking" element={<AccountLinking />} />
<Route path="/MarkdownEditor" element={<MarkdownEditor />} />
</Routes>
);
};
Expand Down