Skip to content

Commit 10589f4

Browse files
committed
헤더 로그인 전후 높이 통일 및 로그인 후 원래 페이지로 이동 기능 구현, 새 게시물 작성 페이지 추가 및 더미 이미지 적용
1 parent dd30c25 commit 10589f4

File tree

9 files changed

+192
-53
lines changed

9 files changed

+192
-53
lines changed

src/App.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ import Shared from "./components/mypage/Shared";
1717
import MyProject from "./components/mypage/MyProject";
1818
import MyCommunity from "./components/mypage/MyCommunity";
1919
import ScrollToTop from "./components/common/ScrollToTop";
20+
import CommunityWrite from "./components/community/CommunityWrite";
21+
2022

2123
function App() {
2224
const [isDark, setIsDark] = useState(false);
@@ -97,16 +99,16 @@ function App() {
9799
<Route path="/login" element={<Login />} />
98100
<Route path="/signup" element={<SignUp />} />
99101

100-
{/* IDE 라우팅 설정 */}
101102
<Route path="/ide" element={<IDE />} />
102103
<Route path="/ide/:param" element={<IDE />} />
103104
<Route path="/ide/:language/:filename" element={<IDE />} />
104105

105106
<Route path="/community" element={<Community />} />
107+
<Route path="/community/write" element={<CommunityWrite />} /> {/* ✅ 추가 */}
108+
106109
<Route path="/broadcast" element={<Codecast />} />
107110
<Route path="/startbroadcast" element={<StartCodecast />} />
108111

109-
{/* MyPage 라우팅 설정 */}
110112
<Route path="/mypage" element={<MyPageLayout nickname={nickname} />}>
111113
<Route index element={<Mypage nickname={nickname} />} />
112114
<Route path="project" element={<MyProject />} />
@@ -115,6 +117,7 @@ function App() {
115117
<Route path="shared" element={<Shared />} />
116118
</Route>
117119
</Routes>
120+
118121
<Footer />
119122
</HashRouter>
120123
);

src/components/community/Community.css

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ body {
66
}
77

88
.community-container {
9-
max-width: 900px;
9+
max-width: 1400px; /* 또는 100%, 1000px 등 */
1010
margin: 0 auto;
1111
padding: 80px 20px;
1212
}
@@ -33,6 +33,7 @@ body {
3333
font-size: 1.25rem; /* 글씨 키움 */
3434
cursor: pointer;
3535
transition: background-color 0.3s;
36+
3637
}
3738

3839

@@ -59,7 +60,7 @@ body {
5960
padding: 1rem 2rem 3rem 2rem; /* 위 여백을 1.5rem으로 줄임 */
6061
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.06);
6162
margin-bottom: 2rem;
62-
width: 97.5%;
63+
width: 100%;
6364
min-height: 600px;
6465
}
6566

@@ -90,7 +91,7 @@ body {
9091
}
9192

9293
.popular-post-card h3 {
93-
font-size: 1.5rem;
94+
font-size: 1.25rem;
9495
font-weight: bold;
9596
margin: 0 0 0.5rem 0;
9697
}

src/components/community/Community.jsx

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import React from "react";
2+
import { useNavigate } from "react-router-dom"; // ✅ navigate import 추가
23
import "./Community.css";
34

45
export default function Community() {
6+
const navigate = useNavigate(); // ✅ navigate 선언
7+
58
const posts = [
69
{
710
title: "버블 정렬 시각화 프로젝트 공유합니다",
@@ -11,7 +14,7 @@ export default function Community() {
1114
date: "2023. 5. 15",
1215
likes: 24,
1316
comments: 8,
14-
thumbnail: "https://via.placeholder.com/300x180"
17+
thumbnail: "https://unsplash.com/photos/KrYbarbAx5s/download?ixid=M3wxMjA3fDB8MXxzZWFyY2h8MTZ8fCVFQiU5NCU5NCVFQiVCMiU4NCVFQSVCOSU4NXxrb3wwfHx8fDE3NDgyNDc1NDh8MA&force=true"
1518
},
1619
{
1720
title: "그래프 탐색 알고리즘 비교: BFS vs DFS",
@@ -21,7 +24,7 @@ export default function Community() {
2124
date: "2023. 5. 17",
2225
likes: 32,
2326
comments: 12,
24-
thumbnail: "https://via.placeholder.com/300x180"
27+
thumbnail: "https://images.unsplash.com/photo-1526374965328-7f61d4dc18c5?auto=format&fit=crop&w=300&h=180"
2528
},
2629
{
2730
title: "동적 프로그래밍 문제 해결 가이드",
@@ -31,15 +34,21 @@ export default function Community() {
3134
date: "2023. 5. 18",
3235
likes: 40,
3336
comments: 15,
34-
thumbnail: "https://via.placeholder.com/300x180"
37+
thumbnail: "https://unsplash.com/photos/ZS67i1HLllo/download?ixid=M3wxMjA3fDB8MXxzZWFyY2h8MTV8fCVFQiU4RiU5OSVFQyVBMCU4MSUyMCVFRCU5NCU4NCVFQiVBMSU5QyVFQSVCNyVCOCVFQiU5RSU5OCVFQiVCMCU4RCUyMCVFRCU5NSVCNCVFQSVCMiVCMCUyMCVFQSVCMCU4MCVFQyU5RCVCNCVFQiU5MyU5Q3xrb3wwfHx8fDE3NDgyNDc3NjB8MA&force=true"
3538
}
3639
];
3740

41+
3842
return (
3943
<div className="community-container">
4044
<div className="community-header">
4145
<h1>커뮤니티</h1>
42-
<button className="new-post-button">+ 새 게시물</button>
46+
<button
47+
className="new-post-button"
48+
onClick={() => navigate("/community/write")}
49+
>
50+
+ 새 게시물
51+
</button>
4352
</div>
4453

4554
<div className="popular-posts-wrapper">
@@ -86,7 +95,7 @@ export default function Community() {
8695
<p>{post.summary}</p>
8796
<div className="post-footer">
8897
<div className="author-info">
89-
<img src="https://via.placeholder.com/32" alt="작성자" />
98+
<img src="https://cdn-icons-png.flaticon.com/512/847/847969.png" alt="작성자" width="32" height="32" />
9099
<div>
91100
<p>{post.author}</p>
92101
<p className="date">{post.date}</p>
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
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;
10+
}
11+
12+
13+
.write-form label {
14+
display: block;
15+
margin-bottom: 1.5rem;
16+
font-weight: bold;
17+
}
18+
19+
.write-form input,
20+
.write-form textarea {
21+
width: 100%;
22+
padding: 0.75rem;
23+
margin-top: 0.5rem;
24+
border: 1px solid #ccc;
25+
border-radius: 6px;
26+
font-size: 1rem;
27+
font-family: inherit;
28+
}
29+
30+
.submit-button {
31+
background-color: #845ef7;
32+
color: white;
33+
padding: 0.75rem 2rem;
34+
border: none;
35+
border-radius: 6px;
36+
font-size: 1.1rem;
37+
cursor: pointer;
38+
}
39+
40+
.submit-button:hover {
41+
background-color: #6f4fd5;
42+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import React, { useState } from "react";
2+
import "./CommunityWrite.css";
3+
import { useNavigate } from "react-router-dom";
4+
5+
const CommunityWrite = () => {
6+
const navigate = useNavigate();
7+
const [title, setTitle] = useState("");
8+
const [content, setContent] = useState("");
9+
const [tags, setTags] = useState("");
10+
11+
const handleSubmit = (e) => {
12+
e.preventDefault();
13+
14+
// 임시 처리: 콘솔에 출력
15+
console.log("제목:", title);
16+
console.log("내용:", content);
17+
console.log("태그:", tags.split(',').map(tag => tag.trim()));
18+
19+
// 추후 API로 전송하거나, 목록에 추가
20+
alert("작성 완료!");
21+
navigate("/community");
22+
};
23+
24+
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>
56+
</div>
57+
);
58+
};
59+
60+
export default CommunityWrite;

src/components/header/Header.css

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
1-
/* Header 전체 스타일 */
21
.custom-header {
2+
position: fixed;
3+
top: 0;
34
width: 100%;
4-
padding: 12px 24px;
5-
background-color: white;
6-
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
7-
display: grid;
8-
grid-template-columns: 1fr auto 1fr;
5+
height: 64px;
6+
display: flex;
7+
justify-content: space-between;
98
align-items: center;
10-
box-sizing: border-box;
11-
font-family: 'Segoe UI', sans-serif;
12-
position: fixed;
9+
padding: 0 24px;
10+
background-color: white;
1311
z-index: 1000;
12+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
1413
}
1514

15+
16+
1617
/* 왼쪽: 로고 */
1718
.header-left {
1819
justify-self: start;
@@ -33,15 +34,22 @@
3334
display: flex;
3435
align-items: center;
3536
gap: 10px;
37+
height: 100%; /* 세로 정렬 일관성 */
3638
}
3739

40+
3841
/* 가운데: 네비게이션 */
3942
.header-nav {
40-
justify-self: center;
43+
position: absolute;
44+
left: 50%;
45+
transform: translateX(-50%);
4146
display: flex;
4247
gap: 20px;
48+
align-items: center;
49+
height: 100%;
4350
}
4451

52+
4553
/* NavLink 기본 상태 */
4654
.header-nav a {
4755
text-decoration: none;
@@ -93,14 +101,18 @@
93101
background-color: #5a0099;
94102
}
95103

104+
.user-menu-container {
105+
position: relative; /* 드롭다운 위치 기준 */
106+
}
107+
96108
.user-nickname {
97-
display: flex;
98-
align-items: center;
99-
font-weight: 600;
100-
cursor: pointer;
101-
font-size: 1.05rem;
109+
white-space: nowrap;
110+
overflow: hidden;
111+
text-overflow: ellipsis;
112+
max-width: 200px;
102113
}
103114

115+
104116
.user-icon {
105117
margin-right: 8px;
106118
vertical-align: middle;
@@ -212,6 +224,8 @@
212224
background-color: #f5f0ff;
213225
}
214226

227+
228+
215229
.dark-mode .user-dropdown {
216230
background-color: #2a2a2a;
217231
border-color: #444;

src/components/header/Header.jsx

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,26 @@
11
import React, { useState } from "react";
2-
import { NavLink, Link, useNavigate } from "react-router-dom";
3-
import { FaMoon, FaSun, FaUserCircle } from "react-icons/fa"; // ✅ FaUserCircle 가져옴
2+
import { NavLink, Link, useNavigate, useLocation } from "react-router-dom";
3+
import { FaMoon, FaSun, FaUserCircle } from "react-icons/fa";
44
import "./Header.css";
55

66
const Header = ({ isDark, setIsDark, isLoggedIn, nickname }) => {
77
const [isMenuOpen, setIsMenuOpen] = useState(false);
88
const navigate = useNavigate();
9+
const location = useLocation(); // ✅ 현재 경로 확인
910

1011
const handleLogout = () => {
1112
localStorage.clear();
12-
navigate("/");
13-
window.location.reload();
13+
14+
if (location.pathname.startsWith("/mypage")) {
15+
navigate("/"); // ✅ 마이페이지일 때만 홈으로 이동
16+
} else {
17+
navigate(location.pathname); // 그대로 현재 페이지 유지
18+
}
19+
20+
window.location.reload(); // 상태 강제 반영
1421
};
1522

23+
1624
const toggleMenu = () => {
1725
setIsMenuOpen(!isMenuOpen);
1826
};
@@ -47,10 +55,7 @@ const Header = ({ isDark, setIsDark, isLoggedIn, nickname }) => {
4755
{isLoggedIn ? (
4856
<div className="user-menu-container">
4957
<span className="user-nickname" onClick={toggleMenu}>
50-
<FaUserCircle
51-
size={24}
52-
className={"user-icon"}
53-
/>
58+
<FaUserCircle size={24} className="user-icon" />
5459
{nickname} 님 ▾
5560
</span>
5661
{isMenuOpen && (
@@ -62,8 +67,16 @@ const Header = ({ isDark, setIsDark, isLoggedIn, nickname }) => {
6267
</div>
6368
) : (
6469
<>
65-
<Link to="/login" className="btn btn-outline">로그인</Link>
66-
<Link to="/signup" className="btn btn-filled">회원가입</Link>
70+
<Link
71+
to="/login"
72+
state={{ from: location.pathname }} // ✅ 현재 경로 전달
73+
className="btn btn-outline"
74+
>
75+
로그인
76+
</Link>
77+
<Link to="/signup" className="btn btn-filled">
78+
회원가입
79+
</Link>
6780
</>
6881
)}
6982
</div>

0 commit comments

Comments
 (0)