Skip to content

Commit f6ce1d7

Browse files
authored
[#201] ✨ 커뮤니티 페이지 개발 (#202)
* [#201] ♻️ margin layout to flex flex layout * [#201] ✨ add community page
1 parent 0d6821f commit f6ce1d7

File tree

3 files changed

+374
-12
lines changed

3 files changed

+374
-12
lines changed

src/app/(pages)/community/page.tsx

Lines changed: 363 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,363 @@
1+
'use client'
2+
3+
import { useState } from 'react'
4+
5+
import { IcPencil, IcSearch } from '@/assets/IconList'
6+
import { cn } from '@/lib/utils'
7+
import type {
8+
CommunityCategory,
9+
CommunityListItem,
10+
CommunityTop5Member,
11+
} from '@/types/api/Community.types'
12+
13+
import { Avatar } from '@/components/common/avatar'
14+
import { Button, Link } from '@/components/common/button'
15+
import { Box, Container } from '@/components/common/containers'
16+
import { TextInput } from '@/components/common/input'
17+
import { Text } from '@/components/common/text'
18+
import { CommunityCard } from '@/components/community/CommunityCard'
19+
import { Pagination } from '@/components/shared/pagination'
20+
21+
import { usePagination } from '@/hooks/usePagination'
22+
23+
export default function CommunityPage(): JSX.Element {
24+
const [order, setOrder] = useState<'recent' | 'like' | 'view'>('recent')
25+
const {
26+
currentPage,
27+
pageButtons,
28+
hasNextPageGroup,
29+
hasPreviousPageGroup,
30+
goToPage,
31+
goToNextPageGroup,
32+
goToPreviousPageGroup,
33+
} = usePagination({ totalItems: 20, itemsPerPage: 10, buttonsPerPage: 10 })
34+
const [communityCategory, setCommunityCategory] =
35+
useState<CommunityCategory | null>(null)
36+
37+
return (
38+
<Container className='mx-auto my-80 flex gap-30'>
39+
<div className='flex w-216 flex-col gap-20'>
40+
<Box className='h-386 items-start justify-start gap-12' padding={20}>
41+
<Text.Title variant='title1' weight='700'>
42+
인기 유저 Top5!
43+
</Text.Title>
44+
{MOCK_FAV_USERS.map(topUser => (
45+
<div key={topUser.member.id} className='flex flex-col gap-6'>
46+
<div className='flex items-center gap-10'>
47+
<Avatar
48+
image={topUser.member.imageUrl}
49+
size={24}
50+
alt={topUser.member.nickname}
51+
/>
52+
<Text.Title variant='title2' weight='700'>
53+
{topUser.member.nickname}
54+
</Text.Title>
55+
</div>
56+
<div className='flex gap-4'>
57+
<Text.Body variant='body3' color='gray500'>
58+
좋아요
59+
</Text.Body>
60+
<Text.Body variant='body3' color='gray500'>
61+
{topUser.totalLikes}
62+
</Text.Body>
63+
</div>
64+
</div>
65+
))}
66+
</Box>
67+
<Box
68+
variant='contained'
69+
color='secondary'
70+
className='h-380 gap-12'
71+
padding={20}
72+
>
73+
<Text.Title
74+
variant='title1'
75+
weight='700'
76+
className='text-common-black'
77+
>
78+
AD
79+
</Text.Title>
80+
</Box>
81+
</div>
82+
<main className='flex-grow'>
83+
<div className='mb-20 flex justify-between gap-12'>
84+
<TextInput
85+
className='h-48'
86+
placeholder='제목, 내용, 작성자를 검색해보세요!'
87+
startAdornment={<IcSearch width={24} height={24} />}
88+
/>
89+
<div className='flex-shrink-0'>
90+
<Button size='lg' className='font-semibold'>
91+
검색
92+
</Button>
93+
</div>
94+
</div>
95+
<div className='mb-20 flex justify-between gap-12'>
96+
<Text.Heading as='h2' variant='heading2'>
97+
커뮤니티
98+
</Text.Heading>
99+
<div>
100+
<Link href={'/team/add'} size='lg' className='w-118 font-semibold'>
101+
<IcPencil width={24} height={24} />
102+
작성하기
103+
</Link>
104+
</div>
105+
</div>
106+
<div className='mb-20 flex items-center justify-between'>
107+
<div className='flex gap-40'>
108+
<Button
109+
onClick={() => {
110+
setCommunityCategory(null)
111+
}}
112+
variant='text'
113+
className={cn(
114+
'h-auto p-0 text-heading5 font-bold text-gray-500',
115+
{
116+
'text-gray-800': communityCategory === null,
117+
}
118+
)}
119+
>
120+
전체
121+
</Button>
122+
<Button
123+
onClick={() => {
124+
setCommunityCategory('SKILL')
125+
}}
126+
variant='text'
127+
className={cn(
128+
'h-auto p-0 text-heading5 font-bold text-gray-500',
129+
{
130+
'text-gray-800': communityCategory === 'SKILL',
131+
}
132+
)}
133+
>
134+
기술
135+
</Button>
136+
<Button
137+
onClick={() => {
138+
setCommunityCategory('CAREER')
139+
}}
140+
variant='text'
141+
className={cn(
142+
'h-auto p-0 text-heading5 font-bold text-gray-500',
143+
{
144+
'text-gray-800': communityCategory === 'CAREER',
145+
}
146+
)}
147+
>
148+
커리어
149+
</Button>
150+
<Button
151+
onClick={() => {
152+
setCommunityCategory('OTHER')
153+
}}
154+
variant='text'
155+
className={cn(
156+
'h-auto p-0 text-heading5 font-bold text-gray-500',
157+
{
158+
'text-gray-800': communityCategory === 'OTHER',
159+
}
160+
)}
161+
>
162+
기타
163+
</Button>
164+
</div>
165+
<div className='flex gap-40'>
166+
<Button
167+
onClick={() => {
168+
setOrder('recent')
169+
}}
170+
variant='text'
171+
className={cn('h-auto p-0 text-gray-500', {
172+
'text-gray-800': order === 'recent',
173+
})}
174+
>
175+
최신순
176+
</Button>
177+
<Button
178+
onClick={() => {
179+
setOrder('like')
180+
}}
181+
variant='text'
182+
className={cn('h-auto p-0 text-gray-500', {
183+
'text-gray-800': order === 'like',
184+
})}
185+
>
186+
좋아요순
187+
</Button>
188+
<Button
189+
onClick={() => {
190+
setOrder('view')
191+
}}
192+
variant='text'
193+
className={cn('h-auto p-0 text-gray-500', {
194+
'text-gray-800': order === 'view',
195+
})}
196+
>
197+
조회순
198+
</Button>
199+
</div>
200+
</div>
201+
<div className='mb-40 flex h-718 flex-col gap-12 overflow-hidden'>
202+
{MOCK_DATA.map(communityItem => (
203+
<CommunityCard
204+
key={communityItem.id}
205+
communityItem={communityItem}
206+
/>
207+
))}
208+
</div>
209+
<Pagination
210+
currentPage={currentPage}
211+
pageButtons={pageButtons}
212+
hasNextPageGroup={hasNextPageGroup}
213+
hasPreviousPageGroup={hasPreviousPageGroup}
214+
goToPage={goToPage}
215+
goToNextPageGroup={goToNextPageGroup}
216+
goToPreviousPageGroup={goToPreviousPageGroup}
217+
/>
218+
</main>
219+
</Container>
220+
)
221+
}
222+
223+
const MOCK_DATA: CommunityListItem[] = [
224+
{
225+
id: 1,
226+
communityCategory: 'SKILL',
227+
communityTitle: '이럴 땐 어떻게 해결해야하나요?',
228+
communityContent:
229+
'어떻게 해야할지 모르겠어요. 여러분의 도움이 필요합니다. 제발 도와주세요...',
230+
writer: {
231+
id: 1,
232+
nickname: 'John Doe',
233+
imageUrl: 'https://picsum.photos/250/250',
234+
},
235+
answers: 5,
236+
likes: 10,
237+
createdAt: '2023-12-01T12:00:00Z',
238+
views: 10,
239+
},
240+
{
241+
id: 2,
242+
communityCategory: 'CAREER',
243+
communityTitle: '백엔드 5년차 이직 고민',
244+
communityContent:
245+
'DFD에 커뮤니티 기능이 있어서 글 써봅니다. 현재 중소기업에서 5년차 백엔드 개발자로 일하고 있습니다. 어느 순간부터 이 직군과 맞지 않는다고 생각 중인..',
246+
writer: {
247+
id: 1,
248+
nickname: 'John Doe',
249+
imageUrl: 'https://picsum.photos/250/250',
250+
},
251+
answers: 1,
252+
likes: 3,
253+
createdAt: '2023-12-01T12:00:00Z',
254+
views: 4,
255+
},
256+
{
257+
id: 3,
258+
communityCategory: 'OTHER',
259+
communityTitle: '아니 이거 맞는지 확인좀 해주세요;;',
260+
communityContent:
261+
'개발 PM 일정 세운 건데 한번 확인좀 해주세요;;; 납득할 수 있는 있게끔 정해야하는데;;; 이게 맞는지 모르겠거든요?',
262+
writer: {
263+
id: 1,
264+
nickname: 'John Doe',
265+
imageUrl: 'https://picsum.photos/250/250',
266+
},
267+
answers: 0,
268+
likes: 0,
269+
createdAt: '2023-12-01T12:00:00Z',
270+
views: 1,
271+
},
272+
{
273+
id: 4,
274+
communityCategory: 'SKILL',
275+
communityTitle: '이럴 땐 어떻게 해결해야하나요?',
276+
communityContent:
277+
'어떻게 해야할지 모르겠어요. 여러분의 도움이 필요합니다. 제발 도와주세요...',
278+
writer: {
279+
id: 1,
280+
nickname: 'John Doe',
281+
imageUrl: 'https://picsum.photos/250/250',
282+
},
283+
answers: 5,
284+
likes: 10,
285+
createdAt: '2023-12-01T12:00:00Z',
286+
views: 10,
287+
},
288+
{
289+
id: 5,
290+
communityCategory: 'CAREER',
291+
communityTitle: '백엔드 5년차 이직 고민',
292+
communityContent:
293+
'DFD에 커뮤니티 기능이 있어서 글 써봅니다. 현재 중소기업에서 5년차 백엔드 개발자로 일하고 있습니다. 어느 순간부터 이 직군과 맞지 않는다고 생각 중인..',
294+
writer: {
295+
id: 1,
296+
nickname: 'John Doe',
297+
imageUrl: 'https://picsum.photos/250/250',
298+
},
299+
answers: 1,
300+
likes: 3,
301+
createdAt: '2023-12-01T12:00:00Z',
302+
views: 4,
303+
},
304+
{
305+
id: 6,
306+
communityCategory: 'OTHER',
307+
communityTitle: '아니 이거 맞는지 확인좀 해주세요;;',
308+
communityContent:
309+
'개발 PM 일정 세운 건데 한번 확인좀 해주세요;;; 납득할 수 있는 있게끔 정해야하는데;;; 이게 맞는지 모르겠거든요?',
310+
writer: {
311+
id: 1,
312+
nickname: 'John Doe',
313+
imageUrl: 'https://picsum.photos/250/250',
314+
},
315+
answers: 0,
316+
likes: 0,
317+
createdAt: '2023-12-01T12:00:00Z',
318+
views: 1,
319+
},
320+
]
321+
322+
const MOCK_FAV_USERS: CommunityTop5Member[] = [
323+
{
324+
member: {
325+
id: 1,
326+
nickname: '닉네임1',
327+
imageUrl: 'https://picsum.photos/250/250',
328+
},
329+
totalLikes: 12345,
330+
},
331+
{
332+
member: {
333+
id: 2,
334+
nickname: '닉네임2',
335+
imageUrl: 'https://picsum.photos/250/250',
336+
},
337+
totalLikes: 12234,
338+
},
339+
{
340+
member: {
341+
id: 3,
342+
nickname: '닉네임3',
343+
imageUrl: 'https://picsum.photos/250/250',
344+
},
345+
totalLikes: 12233,
346+
},
347+
{
348+
member: {
349+
id: 4,
350+
nickname: '닉네임4',
351+
imageUrl: 'https://picsum.photos/250/250',
352+
},
353+
totalLikes: 12232,
354+
},
355+
{
356+
member: {
357+
id: 5,
358+
nickname: '닉네임5',
359+
imageUrl: 'https://picsum.photos/250/250',
360+
},
361+
totalLikes: 12231,
362+
},
363+
]

0 commit comments

Comments
 (0)