Skip to content

Commit d3ec854

Browse files
authored
Merge pull request #216 from Moaguide-develop/feat/articleDetail
Fix: QA Article Page
2 parents d329fe7 + 2d3edab commit d3ec854

File tree

3 files changed

+105
-23
lines changed

3 files changed

+105
-23
lines changed

src/components/common/MobileFooter.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,12 @@ const MobileFooter = () => {
4949
</div>
5050
<div
5151
onClick={() => {
52-
router.push('/practicepage');
52+
router.push('/learning');
5353
}}
5454
className="flex-1 flex flex-col gap-1 items-center">
5555
<div>
5656
<img
57-
src={`${pathname.includes('/practice') ? '/images/footer/practice_active.svg' : '/images/footer/practice.svg'}`}
57+
src={`${pathname.includes('/learning') ? '/images/footer/practice_active.svg' : '/images/footer/practice.svg'}`}
5858
alt=""
5959
/>
6060
</div>

src/components/learning/FilteredContents.tsx

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import viewIcon from '../../../public/images/learning/article_filter_view.svg';
99
import { extractText } from '@/utils/extractText';
1010
import { useLikeStore } from '@/store/articleLike.store';
1111
import { useViewStore } from '@/store/articleView.store';
12+
import ResponsivePagination from './ResponsivePagination';
1213

1314
interface FilteredContentsProps {
1415
contents: FilteredResponse['content'];
@@ -95,7 +96,7 @@ const FilteredContents = ({
9596
<h3 className="text-lg font-bold text-gray-800 mb-4 line-clamp-1">
9697
{item.article.title}
9798
</h3>
98-
<p className="text-sm text-gray-600 line-clamp-2">
99+
<p className="text-sm text-gray-600 line-clamp-2 max-w-full overflow-hidden break-words break-all">
99100
{extractText(item.article.description || '')}
100101
</p>
101102
<div className="text-xs text-gray-500 mt-4 flex items-center justify-end gap-4">
@@ -129,26 +130,11 @@ const FilteredContents = ({
129130
</div>
130131

131132
{totalPages > 1 && (
132-
<div className="flex justify-center mt-8 mb-2">
133-
<ul className="flex items-center space-x-1">
134-
{Array.from({ length: totalPages }, (_, i) => i + 1).map(
135-
(pageNum) => (
136-
<li key={pageNum}>
137-
<button
138-
onClick={() => onPageChange(pageNum)}
139-
className={`w-8 h-8 flex items-center justify-center border rounded ${
140-
page === pageNum
141-
? 'bg-purple-600 text-white'
142-
: 'bg-white text-gray-800 border-gray-300 hover:bg-gray-100'
143-
}`}
144-
>
145-
{pageNum}
146-
</button>
147-
</li>
148-
)
149-
)}
150-
</ul>
151-
</div>
133+
<ResponsivePagination
134+
totalPages={totalPages}
135+
currentPage={page}
136+
onPageChange={onPageChange}
137+
/>
152138
)}
153139
</div>
154140
);
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
'use client';
2+
import { useState, useEffect } from 'react';
3+
import { useRouter, useSearchParams } from 'next/navigation';
4+
import React from 'react';
5+
6+
interface PaginationProps {
7+
totalPages: number;
8+
currentPage: number;
9+
onPageChange: (newPage: number) => void;
10+
}
11+
12+
const ResponsivePagination = ({ totalPages, currentPage, onPageChange }: PaginationProps) => {
13+
const router = useRouter();
14+
const searchParams = useSearchParams();
15+
const [pageNumbers, setPageNumbers] = useState<number[]>([]);
16+
const [currentRange, setCurrentRange] = useState<number>(0);
17+
const [isMobile, setIsMobile] = useState<boolean>(false);
18+
19+
useEffect(() => {
20+
const pageSize = isMobile ? 5 : 10;
21+
const range = Math.floor((currentPage - 1) / pageSize);
22+
setCurrentRange(range);
23+
}, [currentPage, isMobile]);
24+
25+
useEffect(() => {
26+
const checkScreenSize = () => setIsMobile(window.innerWidth < 768);
27+
checkScreenSize();
28+
window.addEventListener('resize', checkScreenSize);
29+
return () => window.removeEventListener('resize', checkScreenSize);
30+
}, []);
31+
32+
useEffect(() => {
33+
const pageSize = isMobile ? 5 : 10;
34+
const start = currentRange * pageSize + 1;
35+
const end = Math.min(start + pageSize - 1, totalPages);
36+
const pages: number[] = [];
37+
for (let i = start; i <= end; i++) {
38+
pages.push(i);
39+
}
40+
setPageNumbers(pages);
41+
}, [currentRange, totalPages, isMobile]);
42+
43+
const handlePageClick = (page: number) => {
44+
onPageChange(page);
45+
const params = new URLSearchParams(searchParams.toString());
46+
params.set('page', page.toString());
47+
router.replace(`?${params.toString()}`, { scroll: false });
48+
};
49+
50+
const handleNextRange = () => {
51+
const pageSize = isMobile ? 5 : 10;
52+
if ((currentRange + 1) * pageSize < totalPages) {
53+
const newRange = currentRange + 1;
54+
setCurrentRange(newRange);
55+
const firstPageOfNextRange = newRange * pageSize + 1;
56+
handlePageClick(firstPageOfNextRange);
57+
}
58+
};
59+
60+
const handlePrevRange = () => {
61+
if (currentRange > 0) {
62+
const pageSize = isMobile ? 5 : 10;
63+
const newRange = currentRange - 1;
64+
setCurrentRange(newRange);
65+
const firstPageOfPrevRange = newRange * pageSize + 1;
66+
handlePageClick(firstPageOfPrevRange);
67+
}
68+
};
69+
70+
return (
71+
<div className="flex justify-center items-center space-x-2 mt-10 mb-10">
72+
<button
73+
onClick={handlePrevRange}
74+
disabled={currentRange === 0}
75+
className="px-3 py-1 border rounded disabled:opacity-50">
76+
&lt;
77+
</button>
78+
{pageNumbers.map((page) => (
79+
<button
80+
key={page}
81+
onClick={() => handlePageClick(page)}
82+
className={`px-3 py-1 border rounded ${page === currentPage ? 'bg-purple-600 text-white' : 'bg-white text-black'}`}>
83+
{page}
84+
</button>
85+
))}
86+
<button
87+
onClick={handleNextRange}
88+
disabled={(currentRange + 1) * (isMobile ? 5 : 10) >= totalPages}
89+
className="px-3 py-1 border rounded disabled:opacity-50">
90+
&gt;
91+
</button>
92+
</div>
93+
);
94+
};
95+
96+
export default ResponsivePagination;

0 commit comments

Comments
 (0)