Skip to content

Commit 1736248

Browse files
Merge pull request #79 from sparcs-kaist/feat/MainPage
Add General Boarrd (PostList) Component
2 parents 0ef939b + 2b0708a commit 1736248

File tree

3 files changed

+282
-230
lines changed

3 files changed

+282
-230
lines changed

src/app/page.tsx

Lines changed: 141 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -2,149 +2,169 @@
22

33
import SearchBar from "@/components/searchBar";
44
import BoardPreview from "@/components/BoardPreview/BoardPreview";
5-
import BoardSelector from "@/components/BoardPreview/BoardSelector";
65
import { useState } from "react";
76
import UserMenu from "@/components/UserMenu/UserMenu";
87
import OtherServices from "@/components/UserMenu/OtherServices";
8+
import Link from "next/link";
9+
10+
// 옵션 타입 정의
11+
interface UIOptions {
12+
showWriter: boolean;
13+
showBoard: boolean;
14+
showProfile: boolean;
15+
showHit: boolean;
16+
showStatus: boolean;
17+
showAttachment: boolean;
18+
showRank: boolean;
19+
showAnswerStatus: boolean;
20+
showTimeAgo: boolean;
21+
}
22+
23+
// 옵션 컨트롤 컴포넌트 타입 정의
24+
interface OptionControlProps {
25+
options: UIOptions;
26+
onChange: (option: string, value: boolean) => void;
27+
}
28+
29+
// 옵션 컨트롤 컴포넌트
30+
const OptionControl = ({ options, onChange }: OptionControlProps) => {
31+
return (
32+
<div className="p-4 bg-white rounded-lg shadow-sm mb-4 border border-gray-200">
33+
<h3 className="text-lg font-bold mb-3">UI 옵션 설정</h3>
34+
<div className="grid grid-cols-3 gap-2">
35+
{Object.entries(options).map(([key, value]) => (
36+
<div key={key} className="flex items-center">
37+
<input
38+
type="checkbox"
39+
id={key}
40+
checked={value}
41+
onChange={() => onChange(key, !value)}
42+
className="mr-2"
43+
/>
44+
<label htmlFor={key} className="text-sm">
45+
{key.replace('show', '')}
46+
</label>
47+
</div>
48+
))}
49+
</div>
50+
</div>
51+
);
52+
};
953

1054
export default function Home() {
1155
const [inputValue, setInputValue] = useState("");
12-
const [board, setBoard] = useState("talk");
13-
14-
const handleBoardSelect = (newBoard: string) => {
15-
setBoard(newBoard); // 🔹 하위 컴포넌트에서 받은 데이터를 상태로 저장
56+
57+
// UI 옵션 상태 관리
58+
const [uiOptions, setUiOptions] = useState<UIOptions>({
59+
showWriter: true,
60+
showBoard: true,
61+
showProfile: false,
62+
showHit: true,
63+
showStatus: true,
64+
showAttachment: true,
65+
showRank: false,
66+
showAnswerStatus: false,
67+
showTimeAgo: true
68+
});
69+
70+
// UI 옵션 변경 핸들러
71+
const handleOptionChange = (option: string, value: boolean) => {
72+
setUiOptions(prev => ({
73+
...prev,
74+
[option]: value
75+
}));
1676
};
1777

18-
const boardData = [
19-
{
20-
type: "top" as const,
21-
title: "🔥 지금 핫한 글",
22-
posts: [
23-
{ id: 1, rank: 1, title: "핫한 소식", image: true, author: "유저1", timeAgo: "9분전", likes: 50, dislikes: 2, comments: 15 },
24-
{ id: 2, rank: 2, title: "이 글 대박임", image: false, author: "유저2", timeAgo: "9분전", likes: 40, dislikes: 3, comments: 10 },
25-
{ id: 10, rank: 3, title: "이 글 대박임", image: false, author: "유저2", timeAgo: "9분전", likes: 40, dislikes: 3, comments: 10 }
26-
],
27-
},
28-
{
29-
type: "all" as const,
30-
title: "🕑 방금 올라온 글",
31-
posts: [
32-
{ id: 3, title: "새로운 정보 공유!", image: true, boardName: "자유게시판", author: "유저3", timeAgo: "9분 전", likes: 5, dislikes: 0, comments: 1 },
33-
{ id: 4, title: "이거 봤어?", image: false, boardName: "공지사항", author: "유저4", timeAgo: "15분 전", likes: 2, dislikes: 1, comments: 0 },
34-
{ id: 127, title: "이거 봤어?", image: false, boardName: "공지사항", author: "유저4", timeAgo: "15분 전", likes: 2, dislikes: 1, comments: 0 },
35-
],
36-
},
37-
{
38-
type: "with-school" as const,
39-
title: "🏫 학교에게 전합니다",
40-
posts: [
41-
{ id: 5, title: "시설 문제 개선 요청", image: false, answered: true, author: "유저5", timeAgo: "1시간 전", likes: 20, dislikes: 3, comments: 5 },
42-
{ id: 6, title: "이 문제 해결해주세요", image: true, answered: false, author: "유저6", timeAgo: "3시간 전", likes: 15, dislikes: 2, comments: 3 },
43-
{ id: 11, title: "이 문제 해결해주세요", image: true, answered: false, author: "유저6", timeAgo: "3시간 전", likes: 15, dislikes: 2, comments: 3 },
44-
45-
],
46-
},
47-
{
48-
type: "talk" as const,
49-
title: "자유게시판",
50-
posts: [
51-
{ id: 7, title: "오늘 하루 어땠나요?", image: false, author: "유저7", likes: 10, dislikes: 1, comments: 2 },
52-
{ id: 8, title: "이거 꿀팁임", image: true, author: "유저8", likes: 25, dislikes: 0, comments: 7 },
53-
{ id: 12, title: "이거 꿀팁임", image: true, author: "유저8", likes: 25, dislikes: 0, comments: 7 },
54-
],
78+
// 테스트 데이터
79+
const testPosts = [
80+
{
81+
id: 1,
82+
title: "게시판 컴포넌트 테스트 글입니다",
83+
author: "개발자",
84+
timeAgo: "9분 전",
85+
likes: 50,
86+
dislikes: 2,
87+
comments: 15,
88+
boardName: "개발 게시판",
89+
hasAttachment: true,
90+
attachmentType: 'image' as const,
91+
hit: 230,
92+
answered: true,
93+
profileImage: "/assets/ServiceAra.svg"
5594
},
56-
{
57-
type: "portal-notice" as const,
58-
title: "포탈 공지",
59-
posts: [
60-
{ id: 21, title: "시설 문제 개선 요청", image: false, answered: true, author: "유저5", timeAgo: "1시간 전", likes: 20, dislikes: 3, comments: 5 },
61-
{ id: 22, title: "이 문제 해결해주세요", image: true, answered: false, author: "유저6", timeAgo: "3시간 전", likes: 15, dislikes: 2, comments: 3 },
62-
{ id: 13, title: "이 문제 해결해주세요", image: true, answered: false, author: "유저6", timeAgo: "3시간 전", likes: 15, dislikes: 2, comments: 3 },
63-
],
95+
{
96+
id: 2,
97+
title: "UI 옵션을 변경해보세요!",
98+
author: "디자이너",
99+
timeAgo: "20분 전",
100+
likes: 40,
101+
dislikes: 3,
102+
comments: 10,
103+
boardName: "디자인 게시판",
104+
hasAttachment: false,
105+
hit: 185,
106+
answered: false
64107
},
65-
{
66-
type: "student-group" as const,
67-
title: "학생단체 및 동아리",
68-
posts: [
69-
{ id: 30, title: "스팍스으으", image: false, answered: true, author: "유저5", timeAgo: "1시간 전", likes: 20, dislikes: 3, comments: 5 },
70-
{ id: 31, title: "이 문제 해결해주세요", image: true, answered: false, author: "유저6", timeAgo: "3시간 전", likes: 15, dislikes: 2, comments: 3 },
71-
{ id: 32, title: "이 문제 해결해주세요", image: true, answered: false, author: "유저6", timeAgo: "3시간 전", likes: 15, dislikes: 2, comments: 3 },
72-
],
73-
},
74-
{
75-
type: "market" as const,
76-
title: "거래",
77-
posts: [
78-
{ id: 33, title: "어은동 원룸", image: false, answered: true, author: "유저5", timeAgo: "1시간 전", likes: 20, dislikes: 3, comments: 5 },
79-
{ id: 34, title: "냐옹", image: true, answered: false, author: "유저6", timeAgo: "3시간 전", likes: 15, dislikes: 2, comments: 3 },
80-
{ id: 35, title: "이 문제 해결해주세요", image: true, answered: false, author: "유저6", timeAgo: "3시간 전", likes: 15, dislikes: 2, comments: 3 },
81-
],
108+
{
109+
id: 3,
110+
title: "프로필 이미지와 순위 표시 테스트",
111+
author: "테스터",
112+
timeAgo: "1시간 전",
113+
likes: 35,
114+
dislikes: 1,
115+
comments: 8,
116+
boardName: "테스트 게시판",
117+
hasAttachment: true,
118+
attachmentType: 'both' as const,
119+
hit: 142,
120+
answered: true,
121+
profileImage: "/assets/ServiceAra.svg"
82122
},
123+
{
124+
id: 4,
125+
title: "첨부파일 표시 기능 확인",
126+
author: "사용자",
127+
timeAgo: "2시간 전",
128+
likes: 25,
129+
dislikes: 0,
130+
comments: 5,
131+
boardName: "일반 게시판",
132+
hasAttachment: true,
133+
attachmentType: 'file' as const,
134+
hit: 98,
135+
answered: false
136+
}
83137
];
138+
84139
return (
85-
<div>
140+
<div className="max-w-[1200px] mx-auto">
86141
<div className="absolute top-0 left-0 w-full h-[400px] bg-gradient-to-b from-[#FFEDD2] to-[#FFFFFF] -z-10"></div>
142+
87143
<div className="h-[220px] w-full flex justify-center items-center">
88144
<SearchBar
89145
value={inputValue}
90-
onChange={(e) => setInputValue(e.target.value)}
146+
onChange={(e: React.ChangeEvent<HTMLInputElement>) => setInputValue(e.target.value)}
147+
/>
148+
</div>
149+
150+
{/* UI 옵션 컨트롤 */}
151+
<div className="mb-6">
152+
<OptionControl
153+
options={uiOptions}
154+
onChange={handleOptionChange}
91155
/>
92156
</div>
93-
<div className="flex w-full px-[80px]">
94-
<div className="flex items-center justify-center p-6 border-[1px] border-gray-200 rounded-[20px] shadow-sm w-[857px] bg-white">
157+
158+
{/* 게시판 프리뷰 테스트 영역 */}
159+
<div className="flex justify-center">
160+
<div className="p-6 border border-gray-200 rounded-[20px] shadow-sm bg-white">
95161
<BoardPreview
96-
type={boardData[0].type}
97-
title={boardData[0].title}
98-
posts={boardData[0].posts}
162+
boardTitle="🧪 게시판 컴포넌트 테스트"
163+
posts={testPosts}
164+
boardLink="/board/test"
165+
{...uiOptions}
99166
/>
100-
<BoardPreview
101-
type={boardData[1].type}
102-
title={boardData[1].title}
103-
posts={boardData[1].posts}
104-
/>
105167
</div>
106-
107-
<div className="bg-white border-[1px] border-gray-200 rounded-[20px] shadow-sm min-w-[355px] p-[20px] space-y-4">
108-
<UserMenu />
109-
<OtherServices />
110-
</div>
111-
</div>
112-
113-
{/*자유게시판 , 포탈공지, 학생 및 단체 동아리, 거래, 소통, 뉴스*/}
114-
<div className ="items-center justify-center p-6 border-[1px] border-gray-200 rounded-[20px] shadow-sm w-[857px]">
115-
<BoardSelector onBoardSelect={handleBoardSelect} />
116-
{board === "talk" && (
117-
<BoardPreview
118-
type={boardData[3].type}
119-
title={boardData[3].title}
120-
posts={boardData[3].posts}
121-
/>)}
122-
{board === "portal-notice" && (
123-
<BoardPreview
124-
type={boardData[4].type}
125-
title={boardData[4].title}
126-
posts={boardData[4].posts}
127-
/>)}
128-
{board === "student-group" && (
129-
<BoardPreview
130-
type={boardData[5].type}
131-
title={boardData[5].title}
132-
posts={boardData[5].posts}
133-
/>)}
134-
{board === "market" && (
135-
<BoardPreview
136-
type={boardData[6].type}
137-
title={boardData[6].title}
138-
posts={boardData[6].posts}
139-
/>)}
140-
</div>
141-
142-
<div className ="items-center justify-center p-6 border-[1px] border-gray-200 rounded-[20px] shadow-sm w-[355px]">
143-
<BoardPreview
144-
type={boardData[2].type}
145-
title={boardData[2].title}
146-
posts={boardData[2].posts}
147-
/>
148168
</div>
149169
</div>
150170
);

0 commit comments

Comments
 (0)