Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat[#98]: 마이페이지 - 등록한 게시글 탭 컨텐츠 구현 #178

Merged
merged 11 commits into from
Mar 22, 2024
Merged
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: 3 additions & 3 deletions src/apis/activities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
REVIEWS_API,
RESERVATIONS_API,
IMAGE_API,
PAGE_SIZE,
DEFAULT_PAGE_SIZE,
PAGE_METHOD,
} from '@/constants';

Expand All @@ -17,7 +17,7 @@ const Activities = {

getList: () =>
instance.get(ACTIVITIES_API, {
params: { size: PAGE_SIZE, method: PAGE_METHOD },
params: { size: DEFAULT_PAGE_SIZE, method: PAGE_METHOD },
}),

getScheduleList: (activityId: number, year: string, month: string) =>
Expand All @@ -27,7 +27,7 @@ const Activities = {

getReviewList: (activityId: number) =>
instance.get(`${ACTIVITIES_API}/${activityId}${REVIEWS_API}`, {
params: { size: PAGE_SIZE },
params: { size: DEFAULT_PAGE_SIZE },
}),

create: (value: ActivityCreateBody) => instance.post(ACTIVITIES_API, value),
Expand Down
6 changes: 3 additions & 3 deletions src/apis/myActivities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {
RESERVATION_DASHBOARD_API,
RESERVED_SCHEDULE_API,
RESERVATIONS_API,
PAGE_SIZE,
DEFAULT_PAGE_SIZE,
} from '@/constants';

import { ReservationStatus, EditReservationStatusBody, MyActivitiesBody } from '@/types';
Expand All @@ -14,7 +14,7 @@ export const MyActivities = {
getList: () =>
instance.get(`${MY_ACTIVITIES_API}`, {
params: {
size: PAGE_SIZE,
size: DEFAULT_PAGE_SIZE,
},
}),

Expand All @@ -36,7 +36,7 @@ export const MyActivities = {
getHourlyReservationList: (activityId: number, scheduleId: number, status: ReservationStatus) =>
instance.get(`${MY_ACTIVITIES_API}/${activityId}${RESERVATIONS_API}`, {
params: {
size: PAGE_SIZE,
size: DEFAULT_PAGE_SIZE,
scheduleId,
status,
},
Expand Down
4 changes: 2 additions & 2 deletions src/apis/myNotifications.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { MY_NOTIFICATIONS_API, PAGE_SIZE } from '@/constants';
import { MY_NOTIFICATIONS_API, DEFAULT_PAGE_SIZE } from '@/constants';

import instance from './axios';

export const MyNotifications = {
get: () =>
instance.get(MY_NOTIFICATIONS_API, {
params: {
size: PAGE_SIZE,
size: DEFAULT_PAGE_SIZE,
},
}),

Expand Down
4 changes: 2 additions & 2 deletions src/apis/myReservations.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { MY_RESERVATIONS_API, PAGE_SIZE, REVIEWS_API } from '@/constants';
import { MY_RESERVATIONS_API, DEFAULT_PAGE_SIZE, REVIEWS_API } from '@/constants';

import { CreateReviewParams, MyReservationsStatus } from '@/types';

Expand All @@ -8,7 +8,7 @@ export const MyReservations = {
get: (status: MyReservationsStatus) =>
instance.get(MY_RESERVATIONS_API, {
params: {
size: PAGE_SIZE,
size: DEFAULT_PAGE_SIZE,
status,
},
}),
Expand Down
4 changes: 2 additions & 2 deletions src/components/commons/Pagination/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import Image from 'next/image';

import classNames from 'classnames/bind';

import { PAGE_SIZE, SVGS } from '@/constants';
import { DEFAULT_PAGE_SIZE, SVGS } from '@/constants';

import usePagination from '@/hooks/usePagination';

Expand Down Expand Up @@ -32,7 +32,7 @@ const Pagination = ({ totalCount, pageState, postPerPage, onClick }: PaginationP
} = usePagination(totalCount, pageState, postPerPage, onClick);

const isArrowActivated = currentPageGroupIndex !== pagesArray.length - 1;
const showPagination = !!totalCount && totalCount !== PAGE_SIZE;
const showPagination = !!totalCount && postPerPage !== DEFAULT_PAGE_SIZE;

return (
showPagination && (
Expand Down
40 changes: 40 additions & 0 deletions src/components/mypage/MyPosts/MyPosts.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
.mypost-container {
@include column-flexbox(start, stretch, 2.4rem);
}

.title-area {
@include flexbox(between, center);
}

.selected-game {
@include flexbox(start, center, 0.8rem);

&-title {
@include text-style(18, $white);
}

&-count {
@include text-style(14, $primary, bold);
}
}

.card {
&-area {
@include column-flexbox(start, stretch, 1.6rem);
}

&-list {
@include column-flexbox(start, stretch, 1.2rem);
}
}

.filter-sort {
@include flexbox(between, center);

position: relative;
}

.dropdown {
flex-shrink: 0;
width: 12rem;
}
113 changes: 113 additions & 0 deletions src/components/mypage/MyPosts/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import { useState } from 'react';

import classNames from 'classnames/bind';

import { GAME_FILTERS, PRICE_TO_POST_TYPES } from '@/constants';
import { formatCategoryToGameNameKR } from '@/utils';
import { getPostPageSize } from '@/utils/getPageSize';

import { RegisteredCard } from '@/components/commons/cards';
import Dropdown from '@/components/commons/Dropdown';
import Filter from '@/components/commons/Filter';
import Pagination from '@/components/commons/Pagination';
import EmptyCard from '@/components/layout/empty/EmptyCard';
import MockActivityDatas from '@/constants/mockData/myActivitiesMockData.json';
import { useDeviceType } from '@/hooks/useDeviceType';
import useProcessedDataList from '@/hooks/useProcessedDataList';

import { ActivityResponse, MyActivitiesResponse, Order, SortOption } from '@/types';

import styles from './MyPosts.module.scss';

const cx = classNames.bind(styles);

const MockApiResponse: MyActivitiesResponse = {
cursorId: 0,
totalCount: 0,
activities: MockActivityDatas,
};

const initialFilter = {
category: GAME_FILTERS[0].id,
};

const initialSortOption: SortOption<ActivityResponse> = {
key: 'createdAt',
type: 'date',
order: 'desc',
};

const dropdownOptions: {
title: string;
value: Order;
}[] = [
{ title: '최신순', value: 'desc' },
{ title: '오래된순', value: 'asc' },
];

const MyPosts = () => {
const [page, setPage] = useState(1);
const [selectFilter, setSelectFilter] = useState(initialFilter);
const [sortOption, setSortOption] = useState(initialSortOption);
const currentDeviceType = useDeviceType();

const pageSize = getPostPageSize(currentDeviceType);

const { pagedDataList, totalCount } = useProcessedDataList({
CheeseB marked this conversation as resolved.
Show resolved Hide resolved
initialDataList: MockApiResponse.activities,
selectFilter,
sortOption,
page,
setPage,
postsPerPage: pageSize,
});

const handleClickPage = (pageNumber: number) => setPage(pageNumber);
const handleSelectFilter = (selectedId: string) => setSelectFilter({ category: selectedId });
const handleOptionChange = (value: string | number) => setSortOption((prev) => ({ ...prev, order: value as Order }));

return (
<div className={cx('mypost-container')}>
<div className={cx('title-area')}>
<h2 className={cx('selected-game')}>
<span className={cx('selected-game-title')}>
{formatCategoryToGameNameKR(selectFilter.category) ?? '전체'}
</span>
<span className={cx('selected-game-count')}>{totalCount}</span>
</h2>
<div className={cx('dropdown', 'sm-only')}>
<Dropdown options={dropdownOptions} onChange={handleOptionChange} isSmall />
</div>
</div>
<div className={cx('card-area')}>
<div className={cx('filter-sort')}>
<Filter items={GAME_FILTERS} selectedFilterId={selectFilter.category} onChange={handleSelectFilter} />
<div className={cx('dropdown', 'sm-hidden')}>
<Dropdown options={dropdownOptions} onChange={handleOptionChange} isSmall />
</div>
</div>
{totalCount ? (
<ul className={cx('card-list')}>
{pagedDataList.map((data) => (
<li key={data.id}>
<RegisteredCard
path={''}
postType={PRICE_TO_POST_TYPES[data.price]}
title={data.title}
CheeseB marked this conversation as resolved.
Show resolved Hide resolved
address={data.address}
category={formatCategoryToGameNameKR(data.category)}
createdAt={data.createdAt}
/>
</li>
))}
</ul>
) : (
<EmptyCard text='No Post' />
)}
</div>
<Pagination totalCount={totalCount} pageState={page} postPerPage={pageSize} onClick={handleClickPage} />
</div>
);
};

export default MyPosts;
3 changes: 2 additions & 1 deletion src/components/mypage/MypageContent/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { MYPAGE_TAB_OPTIONS } from '@/constants';

import ProfileSummary from '@/components/commons/ProfileSummary';
import Tab from '@/components/commons/Tab';
import MyPosts from '@/components/mypage/MyPosts';
import { USER_DATA } from '@/constants/mockData/headerMockData';
import { MY_ACTIVITIES, MY_RESERVATIONS } from '@/constants/mockData/profileSummaryMockData';

Expand All @@ -14,7 +15,7 @@ import styles from './MypageContent.module.scss';
const cx = classNames.bind(styles);

const tabContentMap: TabContent = {
myPost: <div>MyPostTabContent component here</div>,
myPost: <MyPosts />,
myReservation: <div>ReservedTabContent component here</div>,
reservationsStatus: <div>ReservationsStatusTabContent component here</div>,
};
Expand Down
2 changes: 1 addition & 1 deletion src/constants/paging.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export const PAGE_SIZE = 1000;
export const DEFAULT_PAGE_SIZE = 1000;

export const PAGE_METHOD = 'offset';

Expand Down
4 changes: 3 additions & 1 deletion src/constants/postTypes.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { PostTypes } from '@/types';

export const POST_TYPES = {
offline: '오프라인',
online: '온라인',
'clan-recruitment': '클랜 모집',
'game-strategy': '게임 공략',
};

export const PRICE_TO_POST_TYPES = {
export const PRICE_TO_POST_TYPES: Record<number, PostTypes> = {
0: 'offline',
1: 'online',
2: 'clan-recruitment',
Expand Down
2 changes: 1 addition & 1 deletion src/hooks/usePaginatedDataList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const usePaginatedDataList = <T>({ initialDataList, page, setPage, postsPerPage

useEffect(() => {
setPage(1);
}, [initialDataList, setPage]);
}, [initialDataList, postsPerPage, setPage]);

useEffect(() => {
setPagedDataList(initialDataList.filter((data, index) => index >= startIndex && index < endIndex));
Expand Down
9 changes: 9 additions & 0 deletions src/utils/getPageSize.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { DEFAULT_PAGE_SIZE, POSTS_PER_PAGE, REVIEWS_PER_PAGE } from '@/constants';

import { DeviceType } from '@/types';

export const getPostPageSize = (deviceType: DeviceType) =>
deviceType === 'Mobile' ? DEFAULT_PAGE_SIZE : POSTS_PER_PAGE;

export const getReviewPageSize = (deviceType: DeviceType) =>
deviceType === 'Mobile' ? DEFAULT_PAGE_SIZE : REVIEWS_PER_PAGE;