Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion src/pages/List/ListItems.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import MessagesIcon from '../../assets/Icon/Messages.svg';
import ProfileImg from '../../assets/images/profile.png';
import { Avatar } from '../../components/Avatar';
import styles from './ListItems.module.css';

import { useNavigate } from 'react-router-dom';
Expand All @@ -14,7 +15,10 @@ function ListItem({ item }) {

return (
<div className={styles.listItem} onClick={handleClick}>
<img src={ProfileImg} alt="ํ”„๋กœํ•„ ์ด๋ฏธ์ง€" className={styles.profile} />
<Avatar className={styles.profile}>
<Avatar.Image src={item.imageSource} alt={`${item.name} ํ”„๋กœํ•„`} />
<Avatar.Fallback />
</Avatar>

<div className={styles.name}>{item.name}</div>
<div className={styles.question}>
Expand Down
1 change: 1 addition & 0 deletions src/pages/List/ListItems.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
background-color: #ffffff;
box-sizing: border-box;
height: 187px;
cursor: pointer;
}

.profile {
Expand Down
39 changes: 10 additions & 29 deletions src/pages/List/ListPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,12 @@ import styles from './ListPage.module.css';
import { useNavigate } from 'react-router-dom';
import BoxButton from '../../components/Button/BoxButton';
import { useEffect, useMemo, useState } from 'react';
import { instance } from '../../services/instance';
import ListItem from './ListItems';
import MoreMenu from '../../components/Editmenu/Moremenu';
import Reaction from '../../components/Reaction/Reaction';
import { useSubjects } from './hooks/subjectApi';

function List() {
const navigate = useNavigate();

const [list, setList] = useState([]);
const [page, setPage] = useState(1);

const [limit, setLimit] = useState(getLimitWidth());
Expand All @@ -30,6 +27,12 @@ function List() {
return 6;
}

const { list, totalCount } = useSubjects({
page,
limit,
sort: sortType === 'name' ? 'name' : 'time',
});

// ์ฐฝ ํฌ๊ธฐ ๋ณ€๊ฒฝ์‹œ limit ์žฌ์„ค์ •
useEffect(() => {
const handleResize = () => {
Expand All @@ -40,26 +43,6 @@ function List() {
return () => window.removeEventListener('resize', handleResize);
}, []);

// ์•„์ดํ…œ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ ํ•จ์ˆ˜
useEffect(() => {
const fetchAllItems = async () => {
try {
// ์ „์ฒด ์•„์ดํ…œ ์š”์ฒญ 100๊ฐœ ํ•œ๋„
// ์ถ”ํ›„ ๋ณ€๋™ ๊ฐ€๋Šฅ
const response = await instance(`subjects/?limit=100`, {
method: 'GET',
});

const data = await response.json();
setList(data.results);
} catch (e) {
console.error(e);
}
};

fetchAllItems();
}, []);

const totalPage = Math.ceil(list.length / limit);

// page ๊ณ„์‚ฐ
Expand Down Expand Up @@ -103,7 +86,7 @@ function List() {
/>
<div className={styles.listButton}>
<BoxButton isArrow variant="beige" onClick={goToAnswer}>
์งˆ๋ฌธํ•˜๋Ÿฌ ๊ฐ€๊ธฐ
๋‹ต๋ณ€ํ•˜๋Ÿฌ ๊ฐ€๊ธฐ
</BoxButton>
</div>
</header>
Expand All @@ -123,8 +106,8 @@ function List() {
))}
</div>
<Pagination
totalCount={list.length}
page={safePage}
totalCount={totalCount}
page={page}
setPage={setPage}
limit={limit}
/>
Expand All @@ -133,5 +116,3 @@ function List() {
}

export default List;

// ๋ฐ์ดํ„ฐ ํด๋ฆญ์‹œ ๊ฐœ๋ณ„ํ”ผ๋“œ ๋ฐ์ดํ„ฐ๋กœ ์ด๋™
2 changes: 1 addition & 1 deletion src/pages/List/ListPage.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,11 @@ body {
margin-left: 24px;
font-size: 24px;
margin-top: 15px;
justify-content: center;
}

.titleArea {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
width: 100%;
Expand Down
44 changes: 30 additions & 14 deletions src/pages/List/Pagination.jsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,45 @@
import ArrowLeft from '../../assets/Icon/Pagination-left.svg';
import ArrowRight from '../../assets/Icon/Pagination-right.svg';
import { getPagination } from './hooks/pagination';
import styles from './Pagination.module.css';

// ํ•œ ๊ทธ๋ฃน๋‹น ํŽ˜์ด์ง€ ์ˆ˜
const SIZE_PER_PAGE_GROUP = 5;

function Pagination({ totalCount, page, setPage, limit }) {
const totalPage = Math.ceil(totalCount / limit);
if (totalPage <= 1) return null;
const { totalPage, startPage, endPage, isFirstPage, isLastPage } =
getPagination({
totalCount,
page,
limit,
});

if (totalPage === 0) return null;

// ์ด์ „ ํŽ˜์ด์ง€ ์ด๋™
const handlePrev = () => {
if (isFirstPage) return;
setPage(prev => prev - 1);
};

// ๋‹ค์Œ ํŽ˜์ด์ง€ ์ด๋™
const handleNext = () => {
if (isLastPage) return;
setPage(prev => prev + 1);
};

// ํ˜„์žฌ ํŽ˜์ด์ง€ ๊ทธ๋ฃน ๊ณ„์‚ฐ
const groupedPages = Math.floor((page - 1) / SIZE_PER_PAGE_GROUP);
const startPage = groupedPages * SIZE_PER_PAGE_GROUP + 1;
const endPage = Math.min(startPage + SIZE_PER_PAGE_GROUP - 1, totalPage);
// ํŠน์ • ํŽ˜์ด์ง€ ์ด๋™
const handleMove = targetPage => {
if (targetPage === page) return;
setPage(targetPage);
};

// ํŽ˜์ด์ง€ ์ด๋™ ํ•จ์ˆ˜
const handlePrev = () => setPage(prev => Math.max(prev - 1, 1));
const handleNext = () => setPage(prev => Math.min(prev + 1, totalPage));
// 2

return (
<div className={styles.pagination}>
<button
className={styles.pageButtonLeft}
onClick={handlePrev}
disabled={page === 1}
disabled={isFirstPage}
>
<img src={ArrowLeft} alt="์ด์ „ ํŽ˜์ด์ง€" />
</button>
Expand All @@ -36,7 +52,7 @@ function Pagination({ totalCount, page, setPage, limit }) {
<button
key={p}
className={`${styles.pageButton} ${p === page ? styles.active : ''}`}
onClick={() => setPage(p)}
onClick={() => handleMove(p)}
>
{p}
</button>
Expand All @@ -45,7 +61,7 @@ function Pagination({ totalCount, page, setPage, limit }) {
<button
className={styles.pageButtonRight}
onClick={handleNext}
disabled={page === totalPage}
disabled={isLastPage}
>
<img src={ArrowRight} alt="๋‹ค์Œ ํŽ˜์ด์ง€" />
</button>
Expand Down
9 changes: 1 addition & 8 deletions src/pages/List/Pagination.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@
display: flex;
align-items: center;
justify-content: center;
gap: 16.5px;
margin: 20px 0;
gap: 7.5px;
font-family: 'Actor', sans-serif;
margin-top: 46px;
}
Expand Down Expand Up @@ -40,9 +39,3 @@
border: none;
color: var(--gray-40);
}

@media (max-width: 1199px) {
}

@media (max-width: 767px) {
}
35 changes: 35 additions & 0 deletions src/pages/List/hooks/pagination.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// ํŽ˜์ด์ง€ ๋ฒˆํ˜ธ ๊ฐฏ์ˆ˜
const SIZE_PER_PAGE_GROUP = 5;

export function getPagination({ totalCount, page, limit }) {
// ๊ธฐ๋ณธ๊ฐ’ ๋ฐ˜ํ™˜
if (!totalCount || !limit) {
return {
totalPage: 0,
startPage: 0,
endPage: -1,
isFirstPage: true,
isLastPage: true,
};
}

// ์ „์ฒด ํŽ˜์ด์ง€ ์ˆ˜ ๊ณ„์‚ฐ
const totalPage = Math.ceil(totalCount / limit);

const groupPages = Math.floor((page - 1) / SIZE_PER_PAGE_GROUP);

// ์‹œ์ž‘ ํŽ˜์ด์ง€
const startPage = groupPages * SIZE_PER_PAGE_GROUP + 1;

// ๋ ํŽ˜์ด์ง€
const endPage = Math.min(startPage + SIZE_PER_PAGE_GROUP - 1, totalPage);

// ๊ณ„์‚ฐ๋œ ํŽ˜์ด์ง€ ์ „๋ณด ๋ฐ˜ํ™˜
return {
totalPage,
startPage,
endPage,
isFirstPage: page === 1,
isLastPage: page === totalPage,
};
}
41 changes: 41 additions & 0 deletions src/pages/List/hooks/subjectApi.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { useEffect, useState } from 'react';
import { getSubjects } from '../../../services/subjectsApi';

export const useSubjects = ({ page, limit }) => {
const [list, setList] = useState([]);
const [totalCount, setTotalCount] = useState(0);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);

useEffect(() => {
let mounted = true;

const fetchSubjects = async () => {
try {
setLoading(true);

const data = await getSubjects({
limit,
offset: (page - 1) * limit,
});

if (mounted) {
setList(data.results);
setTotalCount(data.count);
}
} catch (e) {
if (mounted) setError(e);
} finally {
if (mounted) setLoading(false);
}
};

fetchSubjects();

return () => {
mounted = false;
};
}, [page, limit]);

return { list, totalCount, loading, error };
};