Skip to content

Commit c3e260d

Browse files
[#212] ✨ 마이페이지 구현 (#213)
* [#212] 🌱 Initial commit for My Page * [#212] ✨ Add IconList * [#212] ✨ development common layout * [#212] ✨ implement profile layout * [#44] ♻️ make label prop optional * [#212] ✨ add deletable func to select * [#50] ✨ add red500 to color options * [#45] ♻️ make label prop optional * [#212] ✨ add sm-close icon to IconList * [#212] ✨ implement MyPage layout and pages * [#212] ✨ implement MyPage activity section with mockdata integration * [#212] ✨ implement MyPage notifications section with mockdata integration * [#212] ♻️ replace 'any' type with specific types * [#212] 🔧 modify n-mockdata * [#212] 🐛 remove unnecessary semicolons to reslove build errors * [#212] 🐛 apply missing pathname handling * [#212] 💄 set minimum height for top-level data containers * [#212] ♻️ apply usePagination hook * [#212] ♻️ Simplify Link using navLinks array * [#212] ✨ apply useCheckboxSelection hook * [#212] ✨ enhance type safety with NotificationType implementation --------- Co-authored-by: Jung Yoonho <[email protected]>
1 parent f17944a commit c3e260d

File tree

24 files changed

+1955
-2
lines changed

24 files changed

+1955
-2
lines changed
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
'use client'
2+
3+
import { Button } from '@/components/common/button'
4+
import { CheckboxInput } from '@/components/common/input'
5+
import { Text } from '@/components/common/text'
6+
import { Pagination } from '@/components/shared/pagination'
7+
8+
import { useCheckboxSelection } from '@/hooks/useCheckboxSelection'
9+
import { usePagination } from '@/hooks/usePagination'
10+
11+
import { mock } from '../mock'
12+
13+
const ITEMS_PER_PAGE = 10
14+
15+
export default function Comments(): JSX.Element {
16+
const {
17+
currentPage,
18+
pageButtons,
19+
hasNextPageGroup,
20+
hasPreviousPageGroup,
21+
goToPage,
22+
goToNextPageGroup,
23+
goToPreviousPageGroup,
24+
} = usePagination({
25+
totalItems: mock.length,
26+
itemsPerPage: ITEMS_PER_PAGE,
27+
})
28+
29+
const currentData = mock.slice(
30+
(currentPage - 1) * ITEMS_PER_PAGE,
31+
currentPage * ITEMS_PER_PAGE
32+
)
33+
34+
const {
35+
selectedItems,
36+
handleCheckboxChange,
37+
handleSelectAll,
38+
isAllSelected,
39+
} = useCheckboxSelection({
40+
totalItems: mock.length,
41+
itemsPerPage: ITEMS_PER_PAGE,
42+
currentPage,
43+
})
44+
45+
return (
46+
<div className='py-34'>
47+
<div className='flex w-954 flex-row border-b-1 border-t-1 border-b-gray-300 border-t-common-black px-20 py-12'>
48+
<div className='flex w-554 flex-col items-center'>
49+
<Text.Title variant='title2' color='gray800'>
50+
제목
51+
</Text.Title>
52+
</div>
53+
<div className='flex w-120 flex-col items-center'>
54+
<Text.Title variant='title2' color='gray800'>
55+
유형
56+
</Text.Title>
57+
</div>
58+
<div className='flex w-120 flex-col items-center'>
59+
<Text.Title variant='title2' color='gray800'>
60+
작성일
61+
</Text.Title>
62+
</div>
63+
<div className='flex w-120 flex-col items-center'>
64+
<Text.Title variant='title2' color='gray800'>
65+
조회
66+
</Text.Title>
67+
</div>
68+
</div>
69+
<div className='min-h-490'>
70+
{currentData.map((post, index) => {
71+
const globalIndex = (currentPage - 1) * ITEMS_PER_PAGE + index
72+
return (
73+
<div
74+
key={index}
75+
className='flex w-954 flex-row items-center border-b-1 border-b-gray-300 px-20 py-12'
76+
>
77+
<CheckboxInput
78+
variant='checkbox'
79+
checked={selectedItems.includes(globalIndex)}
80+
onChange={() => handleCheckboxChange(index)}
81+
/>
82+
<div className='flex w-526 flex-row'>
83+
<Text.Body variant='body2' color='gray800' weight='500'>
84+
{post.Title}
85+
</Text.Body>
86+
<Text.Title
87+
variant='title2'
88+
color='red500'
89+
weight='700'
90+
className='pl-2'
91+
>
92+
[{post.Comments}]
93+
</Text.Title>
94+
</div>
95+
<div className='flex w-120 flex-row justify-center'>
96+
<Text.Body variant='body2' color='gray800' weight='500'>
97+
{post.Category}
98+
</Text.Body>
99+
</div>
100+
<div className='flex w-120 flex-row justify-center'>
101+
<Text.Body variant='body2' color='gray800' weight='500'>
102+
{post.Date}
103+
</Text.Body>
104+
</div>
105+
<div className='flex w-120 flex-row justify-center'>
106+
<Text.Body variant='body2' color='gray800' weight='500'>
107+
{post.Views}
108+
</Text.Body>
109+
</div>
110+
</div>
111+
)
112+
})}
113+
</div>
114+
<div className='flex flex-row justify-between py-20'>
115+
<CheckboxInput
116+
variant='checkbox'
117+
label='전체선택'
118+
checked={isAllSelected}
119+
onChange={handleSelectAll}
120+
/>
121+
<Button>삭제</Button>
122+
</div>
123+
<Pagination
124+
currentPage={currentPage}
125+
pageButtons={pageButtons}
126+
hasNextPageGroup={hasNextPageGroup}
127+
hasPreviousPageGroup={hasPreviousPageGroup}
128+
goToPage={goToPage}
129+
goToNextPageGroup={goToNextPageGroup}
130+
goToPreviousPageGroup={goToPreviousPageGroup}
131+
/>
132+
</div>
133+
)
134+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
'use client'
2+
3+
import Link from 'next/link'
4+
import { usePathname } from 'next/navigation'
5+
6+
import { Text } from '@/components/common/text'
7+
8+
const navLinks = [
9+
{
10+
path: '/mypage/activity/myposts',
11+
label: '작성 글',
12+
activePaths: ['/mypage/activity/myposts', '/mypage/activity'],
13+
width: 'w-45',
14+
},
15+
{
16+
path: '/mypage/activity/comments',
17+
label: '댓글',
18+
activePaths: ['/mypage/activity/comments'],
19+
width: 'w-28',
20+
},
21+
{
22+
path: '/mypage/activity/likeposts',
23+
label: '좋아요한 글',
24+
activePaths: ['/mypage/activity/likeposts'],
25+
width: 'w-72',
26+
},
27+
]
28+
29+
const ActivityLayout = ({
30+
children,
31+
}: {
32+
children: React.ReactNode
33+
}): JSX.Element => {
34+
const pathname = usePathname()
35+
36+
return (
37+
<div className='h-auto max-w-954'>
38+
<Text.Heading as='h2' variant='heading2' className='pb-8 pt-33'>
39+
활동내역
40+
</Text.Heading>
41+
<Text.Body variant='body2' color='gray600' className='pb-20'>
42+
내가 작성한 글, 댓글, 좋아요한 글 등 모든 활동 내용을 확인할 수
43+
있습니다.
44+
</Text.Body>
45+
<div className='flex w-954 flex-col'>
46+
<div className='flex gap-x-40'>
47+
{navLinks.map(({ path, label, activePaths, width }) => (
48+
<Link key={path} href={path} className={`h-24 ${width}`}>
49+
{activePaths.includes(pathname) ? (
50+
<Text.Title
51+
variant='title2'
52+
color='gray800'
53+
weight='700'
54+
className='border-b-2 border-primary-normal pb-12'
55+
>
56+
{label}
57+
</Text.Title>
58+
) : (
59+
<Text.Body variant='body2' color='gray800'>
60+
{label}
61+
</Text.Body>
62+
)}
63+
</Link>
64+
))}
65+
</div>
66+
</div>
67+
<div>{children}</div>
68+
</div>
69+
)
70+
}
71+
72+
export default ActivityLayout
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
'use client'
2+
3+
import { Button } from '@/components/common/button'
4+
import { CheckboxInput } from '@/components/common/input'
5+
import { Text } from '@/components/common/text'
6+
import { Pagination } from '@/components/shared/pagination'
7+
8+
import { useCheckboxSelection } from '@/hooks/useCheckboxSelection'
9+
import { usePagination } from '@/hooks/usePagination'
10+
11+
import { mock } from '../mock'
12+
13+
const ITEMS_PER_PAGE = 10
14+
15+
export default function LikePosts(): JSX.Element {
16+
const {
17+
currentPage,
18+
pageButtons,
19+
hasNextPageGroup,
20+
hasPreviousPageGroup,
21+
goToPage,
22+
goToNextPageGroup,
23+
goToPreviousPageGroup,
24+
} = usePagination({
25+
totalItems: mock.length,
26+
itemsPerPage: ITEMS_PER_PAGE,
27+
})
28+
29+
const currentData = mock.slice(
30+
(currentPage - 1) * ITEMS_PER_PAGE,
31+
currentPage * ITEMS_PER_PAGE
32+
)
33+
34+
const {
35+
selectedItems,
36+
handleCheckboxChange,
37+
handleSelectAll,
38+
isAllSelected,
39+
} = useCheckboxSelection({
40+
totalItems: mock.length,
41+
itemsPerPage: ITEMS_PER_PAGE,
42+
currentPage,
43+
})
44+
45+
return (
46+
<div className='py-34'>
47+
<div className='flex w-954 flex-row border-b-1 border-t-1 border-b-gray-300 border-t-common-black px-20 py-12'>
48+
<div className='flex w-554 flex-col items-center'>
49+
<Text.Title variant='title2' color='gray800'>
50+
제목
51+
</Text.Title>
52+
</div>
53+
<div className='flex w-120 flex-col items-center'>
54+
<Text.Title variant='title2' color='gray800'>
55+
유형
56+
</Text.Title>
57+
</div>
58+
<div className='flex w-120 flex-col items-center'>
59+
<Text.Title variant='title2' color='gray800'>
60+
작성일
61+
</Text.Title>
62+
</div>
63+
<div className='flex w-120 flex-col items-center'>
64+
<Text.Title variant='title2' color='gray800'>
65+
조회
66+
</Text.Title>
67+
</div>
68+
</div>
69+
<div className='min-h-490'>
70+
{currentData.map((post, index) => {
71+
const globalIndex = (currentPage - 1) * ITEMS_PER_PAGE + index
72+
return (
73+
<div
74+
key={index}
75+
className='flex w-954 flex-row items-center border-b-1 border-b-gray-300 px-20 py-12'
76+
>
77+
<CheckboxInput
78+
variant='checkbox'
79+
checked={selectedItems.includes(globalIndex)}
80+
onChange={() => handleCheckboxChange(index)}
81+
/>
82+
<div className='flex w-526 flex-row'>
83+
<Text.Body variant='body2' color='gray800' weight='500'>
84+
{post.Title}
85+
</Text.Body>
86+
<Text.Title
87+
variant='title2'
88+
color='red500'
89+
weight='700'
90+
className='pl-2'
91+
>
92+
[{post.Comments}]
93+
</Text.Title>
94+
</div>
95+
<div className='flex w-120 flex-row justify-center'>
96+
<Text.Body variant='body2' color='gray800' weight='500'>
97+
{post.Category}
98+
</Text.Body>
99+
</div>
100+
<div className='flex w-120 flex-row justify-center'>
101+
<Text.Body variant='body2' color='gray800' weight='500'>
102+
{post.Date}
103+
</Text.Body>
104+
</div>
105+
<div className='flex w-120 flex-row justify-center'>
106+
<Text.Body variant='body2' color='gray800' weight='500'>
107+
{post.Views}
108+
</Text.Body>
109+
</div>
110+
</div>
111+
)
112+
})}
113+
</div>
114+
<div className='flex flex-row justify-between py-20'>
115+
<CheckboxInput
116+
variant='checkbox'
117+
label='전체선택'
118+
checked={isAllSelected}
119+
onChange={handleSelectAll}
120+
/>
121+
<Button>삭제</Button>
122+
</div>
123+
<Pagination
124+
currentPage={currentPage}
125+
pageButtons={pageButtons}
126+
hasNextPageGroup={hasNextPageGroup}
127+
hasPreviousPageGroup={hasPreviousPageGroup}
128+
goToPage={goToPage}
129+
goToNextPageGroup={goToNextPageGroup}
130+
goToPreviousPageGroup={goToPreviousPageGroup}
131+
/>
132+
</div>
133+
)
134+
}

0 commit comments

Comments
 (0)