Skip to content

Commit 1ed7849

Browse files
authored
Merge pull request #68 from DMU-DebugVisual/sunwoong
커뮤니티 글쓰기 페이지 마크다운 툴바 및 UI 개선
2 parents 0a457a4 + 1d181b2 commit 1ed7849

File tree

3 files changed

+243
-73
lines changed

3 files changed

+243
-73
lines changed

src/components/community/Community.jsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,9 @@ export default function Community() {
150150
<button key={i} className={i === 0 ? "active" : ""}>{filter}</button>
151151
))}
152152
</div>
153-
<button className="write-btn">✏️ 글쓰기</button>
153+
<button className="write-btn" onClick={() => navigate("/community/write")}>
154+
✏️ 글쓰기
155+
</button>
154156
</div>
155157

156158
<div className="post-list">
Lines changed: 163 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,179 @@
1-
.write-container {
2-
max-width: 1000px;
3-
width: 100%;
4-
margin: 100px auto 120px auto; /* ✅ 위아래 여백 + 가운데 정렬 */
5-
padding: 2rem;
6-
background: white;
7-
border-radius: 8px;
8-
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
9-
font-family: 'Noto Sans KR', sans-serif;
1+
.community-write-page {
2+
padding-top: 72px;
3+
max-width: 640px; /* ✅ 가로 폭 줄임 */
4+
margin: 0 auto 40px auto;
5+
padding-left: 16px;
6+
padding-right: 16px;
7+
font-family: "Noto Sans KR", sans-serif;
108
}
119

10+
.top-nav {
11+
margin-top: 10px;
12+
display: flex;
13+
gap: 20px;
14+
margin-bottom: 24px; /* ✅ 질문~제목 입력칸 간격 늘림 */
15+
font-size: 16px;
16+
font-weight: 500;
17+
color: #444;
18+
border-bottom: 1.5px solid #ccc;
19+
padding-bottom: 4px;
20+
}
1221

13-
.write-form label {
22+
.title-input,
23+
.tag-input {
1424
display: block;
15-
margin-bottom: 1.5rem;
16-
font-weight: bold;
25+
width: 100%;
26+
margin-bottom: 8px;
27+
font-size: 16px;
28+
padding: 8px 0;
29+
border: none;
30+
border-bottom: 1px solid transparent;
31+
background-color: transparent;
32+
outline: none;
1733
}
1834

19-
.write-form input,
20-
.write-form textarea {
21-
width: 100%;
22-
padding: 0.75rem;
23-
margin-top: 0.5rem;
35+
.title-input::placeholder {
36+
font-size: 20px;
37+
font-weight: 600;
38+
}
39+
40+
.tag-input::placeholder {
41+
font-size: 14px;
42+
color: #888;
43+
}
44+
45+
.markdown-toolbar {
46+
display: flex;
47+
flex-wrap: wrap;
48+
gap: 8px;
49+
margin-bottom: 8px;
50+
}
51+
52+
.markdown-toolbar button {
53+
width: 36px;
54+
height: 36px;
55+
background: #f1f1f1;
2456
border: 1px solid #ccc;
2557
border-radius: 6px;
26-
font-size: 1rem;
27-
font-family: inherit;
58+
font-size: 16px;
59+
display: flex;
60+
align-items: center;
61+
justify-content: center;
62+
cursor: pointer;
63+
transition: background 0.2s;
2864
}
2965

30-
.submit-button {
31-
background-color: #845ef7;
32-
color: white;
33-
padding: 0.75rem 2rem;
66+
.markdown-toolbar button:hover {
67+
background: #e2e2e2;
68+
}
69+
70+
.content-textarea {
71+
width: 100%;
72+
min-height: 600px; /* ✅ 세로 길이 늘림 */
73+
resize: vertical;
74+
padding: 12px;
75+
font-size: 15px;
76+
line-height: 1.6;
77+
border: 1px solid #ccc;
78+
border-radius: 8px;
79+
}
80+
81+
.placeholder-style {
82+
color: #999;
83+
}
84+
85+
.write-actions {
86+
display: flex;
87+
justify-content: flex-end;
88+
margin-top: 20px;
89+
gap: 12px;
90+
}
91+
92+
.cancel-btn,
93+
.submit-btn {
94+
padding: 8px 16px;
3495
border: none;
3596
border-radius: 6px;
36-
font-size: 1.1rem;
97+
font-weight: 500;
98+
font-size: 14px;
3799
cursor: pointer;
38100
}
39101

40-
.submit-button:hover {
41-
background-color: #6f4fd5;
102+
.cancel-btn {
103+
background-color: #eee;
104+
color: #333;
105+
}
106+
107+
.submit-btn {
108+
background-color: #6a1b9a;
109+
color: #fff;
110+
}
111+
112+
/* 🌙 다크모드: CommunityWrite 페이지 */
113+
.dark-mode .community-write-page {
114+
background-color: #1e1e1e;
115+
color: #f0f0f0;
116+
}
117+
118+
/* 상단 탭 */
119+
.dark-mode .top-nav span {
120+
color: #ccc;
121+
}
122+
123+
.dark-mode .top-nav span.active {
124+
color: #b88eff;
125+
border-bottom: 2px solid #b88eff;
126+
}
127+
128+
/* 제목 입력 */
129+
.dark-mode .title-input {
130+
color: #f0f0f0;
131+
background-color: transparent;
132+
}
133+
134+
.dark-mode .title-input::placeholder {
135+
color: #aaa;
136+
}
137+
138+
/* 태그 입력 */
139+
.dark-mode .tag-input {
140+
color: #ccc;
141+
background-color: transparent;
142+
}
143+
144+
.dark-mode .tag-input::placeholder {
145+
color: #777;
146+
}
147+
148+
/* 마크다운 툴바 버튼 */
149+
.dark-mode .markdown-toolbar button {
150+
background-color: #2a2a2a;
151+
color: #f0f0f0;
152+
border: 1px solid #555;
153+
}
154+
155+
.dark-mode .markdown-toolbar button:hover {
156+
background-color: #3a3a3a;
157+
}
158+
159+
/* 게시물 작성 textarea */
160+
.dark-mode .content-textarea {
161+
background-color: #2a2a2a;
162+
color: #f0f0f0;
163+
border: 1px solid #555;
164+
}
165+
166+
.dark-mode .placeholder-style {
167+
color: #777;
168+
}
169+
170+
/* 등록, 취소 버튼 */
171+
.dark-mode .submit-btn {
172+
background-color: #b88eff;
173+
color: white;
174+
}
175+
176+
.dark-mode .cancel-btn {
177+
background-color: #444;
178+
color: #ccc;
42179
}
Lines changed: 77 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,91 @@
11
import React, { useState } from "react";
2+
import {
3+
FaBold, FaItalic, FaStrikethrough, FaLink, FaPalette, FaCode, FaQuoteRight,
4+
FaImage, FaHeading, FaListUl, FaListOl, FaMinus
5+
} from "react-icons/fa";
26
import "./CommunityWrite.css";
3-
import { useNavigate } from "react-router-dom";
47

5-
const CommunityWrite = () => {
6-
const navigate = useNavigate();
8+
export default function CommunityWrite() {
9+
const defaultGuide = `- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요!
10+
- 마크다운, 단축키를 이용해서 편리하게 글을 작성할 수 있어요.
11+
- 먼저 유사한 질문이 있었는지 검색해보세요.
12+
- 서로를 배려하며 기본 존중하는 문화를 만들어가요.`;
13+
714
const [title, setTitle] = useState("");
8-
const [content, setContent] = useState("");
915
const [tags, setTags] = useState("");
16+
const [content, setContent] = useState(defaultGuide);
17+
18+
const handleFocus = () => {
19+
if (content === defaultGuide) setContent("");
20+
};
1021

11-
const handleSubmit = (e) => {
12-
e.preventDefault();
22+
const handleBlur = () => {
23+
if (content.trim() === "") setContent(defaultGuide);
24+
};
25+
26+
const handleSubmit = () => {
27+
if (!title || content === defaultGuide || content.trim() === "") {
28+
alert("제목과 내용을 작성해주세요!");
29+
return;
30+
}
1331

14-
// 임시 처리: 콘솔에 출력
1532
console.log("제목:", title);
33+
console.log("태그:", tags);
1634
console.log("내용:", content);
17-
console.log("태그:", tags.split(',').map(tag => tag.trim()));
18-
19-
// 추후 API로 전송하거나, 목록에 추가
20-
alert("작성 완료!");
21-
navigate("/community");
2235
};
2336

2437
return (
25-
<div className="write-container">
26-
<h2>📌 새 게시물 작성</h2>
27-
<form className="write-form" onSubmit={handleSubmit}>
28-
<label>
29-
제목
30-
<input
31-
type="text"
32-
value={title}
33-
onChange={(e) => setTitle(e.target.value)}
34-
required
35-
/>
36-
</label>
37-
<label>
38-
내용
39-
<textarea
40-
value={content}
41-
onChange={(e) => setContent(e.target.value)}
42-
rows="10"
43-
required
44-
/>
45-
</label>
46-
<label>
47-
태그 (쉼표로 구분)
48-
<input
49-
type="text"
50-
value={tags}
51-
onChange={(e) => setTags(e.target.value)}
52-
/>
53-
</label>
54-
<button type="submit" className="submit-button">작성하기</button>
55-
</form>
38+
<div className="community-write-page">
39+
<div className="top-nav">
40+
<span>질문</span>
41+
<span>고민있어요</span>
42+
<span>스터디</span>
43+
<span>팀 프로젝트</span>
44+
</div>
45+
46+
<input
47+
type="text"
48+
className="title-input"
49+
placeholder="제목에 핵심 내용을 요약해보세요."
50+
value={title}
51+
onChange={(e) => setTitle(e.target.value)}
52+
/>
53+
54+
<input
55+
type="text"
56+
className="tag-input"
57+
placeholder="태그를 설정하세요 (최대 10개)"
58+
value={tags}
59+
onChange={(e) => setTags(e.target.value)}
60+
/>
61+
62+
<div className="markdown-toolbar">
63+
<button><FaBold /></button>
64+
<button><FaItalic /></button>
65+
<button><FaStrikethrough /></button>
66+
<button><FaLink /></button>
67+
<button><FaPalette /></button>
68+
<button><FaCode /></button>
69+
<button><FaQuoteRight /></button>
70+
<button><FaImage /></button>
71+
<button><FaHeading /></button>
72+
<button><FaListUl /></button>
73+
<button><FaListOl /></button>
74+
<button><FaMinus /></button>
75+
</div>
76+
77+
<textarea
78+
className={`content-textarea ${content === defaultGuide ? "placeholder-style" : ""}`}
79+
value={content}
80+
onChange={(e) => setContent(e.target.value)}
81+
onFocus={handleFocus}
82+
onBlur={handleBlur}
83+
/>
84+
85+
<div className="write-actions">
86+
<button className="cancel-btn">취소</button>
87+
<button className="submit-btn" onClick={handleSubmit}>등록</button>
88+
</div>
5689
</div>
5790
);
58-
};
59-
60-
export default CommunityWrite;
91+
}

0 commit comments

Comments
 (0)