Skip to content

Commit

Permalink
✨ : 프로필 최근 전적에 무한 스크롤 적용
Browse files Browse the repository at this point in the history
  • Loading branch information
jeongbbn committed Nov 25, 2021
1 parent bb87317 commit cb1a1d1
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 77 deletions.
21 changes: 6 additions & 15 deletions back-end/api-server/routes/profile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ ProfileRouter.post('/total', async (req, res, next) => {
try {
const [{ oauth_id }] = await getOauthId(req.body.nickname);
const totalList = await getTotalInDB(oauth_id);
const recentList = await getRecentInDB(oauth_id);
const [total, win] = totalList;
res.status(200).json({ total, win, recentList });
const data = { ...total[0], ...win[0] };
res.status(200).json(data);
} catch (error) {
console.log(error);
res.status(401).json({ error: '잘못된 인증입니다.' });
Expand All @@ -36,9 +36,10 @@ ProfileRouter.post('/recent', async (req, res, next) => {
try {
const { nickname, offset, limit } = req.body;
const [{ oauth_id }] = await getOauthId(nickname);
const recentList = await getRecentInDB_new(oauth_id, offset, limit);
res.status(200).json({ recentList });
const data = await getRecentInDB(oauth_id, offset, limit);
res.status(200).json(data);
} catch (error) {
console.log(error);
res.status(401).json({ error: '잘못된 인증입니다.' });
}
});
Expand Down Expand Up @@ -92,17 +93,7 @@ const getTotalInDB = async (id) => {
]);
};

const getRecentInDB = (id) => {
return innerJoinTable(
'game_date, game_mode, ranking, play_time, attack_cnt, attacked_cnt',
'PLAY',
'GAME_INFO',
'PLAY.game_id = GAME_INFO.game_id',
`oauth_id='${id}'`
);
};

const getRecentInDB_new = (id, offset, limit) => {
const getRecentInDB = (id, offset, limit) => {
return innerJoinTable(
'game_date, game_mode, ranking, play_time, attack_cnt, attacked_cnt',
'PLAY',
Expand Down
4 changes: 0 additions & 4 deletions front-end/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ import RankingPage from './pages/RankingPage';
import ErrorPage from './pages/ErrorPage';
import './App.scss';

import Test1 from './components/InfiniteScroll';

function App() {
let { auth } = useAuth();
const dispatch = useAppDispatch();
Expand Down Expand Up @@ -57,8 +55,6 @@ function App() {
<Route path="rank" element={<RankingPage />} />
<Route path="profile/:nickname" element={<ProfilePage />} />
<Route path="error/:title" element={<ErrorPage />} />

<Route path="test" element={<Test1 />} />
</Route>
</Routes>
</div>
Expand Down
55 changes: 42 additions & 13 deletions front-end/src/components/InfiniteScroll/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,35 @@
import React, { useCallback, useEffect, useRef, useState } from 'react';
import './style.scss';

export default function InfinityScroll() {
const MAX_ROWS = 5;
const drawRecent = (list: Array<any>) => {
if (list.length === 0) return;
return (
<>
{list.map((value) => (
<div className="recent__list" key={value.game_id}>
<div>{value.game_date.slice(0, 10)}</div>
<div>{value.game_mode === 'normal' ? '일반전' : '1 vs 1'}</div>
<div>{value.ranking}</div>
<div>{value.play_time}</div>
<div>{value.attack_cnt}</div>
<div>{value.attacked_cnt}</div>
</div>
))}
</>
);
};

export default function InfiniteScroll({
nickname,
MAX_ROWS,
fetchURL,
type,
}: {
nickname: string | undefined;
MAX_ROWS: number;
fetchURL: string;
type: string;
}) {
const [pageNum, setPageNum] = useState(0);
const [loading, setLoading] = useState(false);

Expand All @@ -13,20 +39,22 @@ export default function InfinityScroll() {
const [list, setList] = useState<any>([]);
const [hasMore, setHasMore] = useState(false);

useEffect(() => console.log(hasMore), [hasMore]);

useEffect(() => {
setLoading(true);

fetch('/api/profile/recent', {
console.log(pageNum);
fetch(fetchURL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ nickname: '뭐', limit: MAX_ROWS, offset: pageNum }),
body: JSON.stringify({ nickname, limit: MAX_ROWS, offset: pageNum }),
})
.then((res) => res.json())
.then((data) => {
setList((prev: any) => {
return [...prev, ...data.recentList];
return [...prev, ...data];
});
setHasMore(data.recentList.length > 0);
setHasMore(data.length > 0);
setLoading(false);
})
.catch((error) => {
Expand All @@ -39,7 +67,7 @@ export default function InfinityScroll() {
if (loading) return;
let options = {
root: rootRef.current,
rootMargin: '0px',
rootMargin: '50px',
threshold: 0,
};

Expand All @@ -55,12 +83,13 @@ export default function InfinityScroll() {
);

return (
<div className="ScrollContainer" ref={rootRef}>
{list.map((m: any, i: number) => {
return <div key={i}>{m['game_date']}</div>;
})}
<div
className={`fancy__scroll ${type === 'profile' ? 'recent__list--scroll' : ''}`}
ref={rootRef}
>
{type === 'profile' && drawRecent(list)}
<div ref={targetRef}></div>
<>{loading && <div>로딩중</div>}</>
<>{loading && <div className="loading">로딩중</div>}</>
</div>
);
}
16 changes: 13 additions & 3 deletions front-end/src/components/InfiniteScroll/style.scss
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
.ScrollContainer {
background-color: rosybrown;
height: 100px;
@import 'common/styles/base';

.recent__list--scroll {
height: 250px;
overflow-y: scroll;

.recent__list {
display: grid;
grid-template-columns: repeat(6, 1fr);
text-align: center;
font-size: 17px;
padding: 15px 40px;
box-sizing: border-box;
}
}
41 changes: 13 additions & 28 deletions front-end/src/pages/ProfilePage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { useNavigate, useParams } from 'react-router-dom';
import { useAppDispatch } from '../../app/hooks';
import { updateNickname } from '../../features/user/userSlice';
import { useSocket } from '../../context/SocketContext';
import InfiniteScroll from '../../components/InfiniteScroll';

export default function Profile() {
const { nickname } = useParams();
Expand All @@ -18,12 +19,14 @@ export default function Profile() {
const translations = [
['total_game_cnt', '총 게임 수'],
['total_play_time', '총 플레이 시간'],
['single_player_win', '1vs1 승리 횟수'],
['single_player_win', '1 vs 1 승리 횟수'],
['multi_player_win', '일반전 승리 횟수'],
['total_attack_cnt', '총 공격 횟수'],
];

const [recentList, setRecentList] = useState<string[][]>([]);
const [statsticsState, setStatsticsState] = useState({});

const [editMode, setEditMode] = useState(false);
const [userState, setUserState] = useState({
id: authProfile.id,
Expand All @@ -49,24 +52,6 @@ export default function Profile() {
);
};

const drawRecent = (recentList: Array<any>) => {
if (recentList.length === 0) return;
return (
<>
{recentList.map((value) => (
<div className="recent-list" key={value.game_date}>
<div>{value.game_date.slice(0, 10)}</div>
<div>{value.game_mode === 'normal' ? '일반전' : '1 vs 1'}</div>
<div>{value.ranking}</div>
<div>{value.play_time}</div>
<div>{value.attack_cnt}</div>
<div>{value.attacked_cnt}</div>
</div>
))}
</>
);
};

const changeTextArea = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
if (!e.target) return;
setUserState({ ...userState, stateMessage: e.target.value });
Expand Down Expand Up @@ -98,8 +83,6 @@ export default function Profile() {
};

useEffect(() => {
setUserState({ ...userState, nickname });

fetch('/api/profile/stateMessage', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
Expand All @@ -121,15 +104,13 @@ export default function Profile() {
})
.then((res) => res.json())
.then((data) => {
setStatsticsState({ ...statsticsState, ...data.total[0], ...data.win[0] });
setRecentList([...data.recentList]);
setStatsticsState({ ...statsticsState, ...data });
})
.catch((error) => {
navigate('/error/unauthorize', { replace: true });
console.log('error:', error);
});
return () => {};
}, [nickname]);
}, []);

return (
<AppbarLayout>
Expand Down Expand Up @@ -164,7 +145,7 @@ export default function Profile() {
)}
</div>
<div className="total-section">
<div className="statistics-section ">
<div className="statistics-section">
<div className="absolute_border_bottom statistics-section__header">
<SectionTitle>통계</SectionTitle>
</div>
Expand All @@ -179,8 +160,12 @@ export default function Profile() {
<div key={value}>{value}</div>
))}
</div>

<div className="recent-list__scroll fancy__scroll">{drawRecent(recentList)}</div>
<InfiniteScroll
nickname={userState.nickname}
MAX_ROWS={5}
fetchURL="/api/profile/recent"
type="profile"
/>
</div>
</div>
</div>
Expand Down
14 changes: 0 additions & 14 deletions front-end/src/pages/ProfilePage/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -124,20 +124,6 @@
margin: 20px 30px 0px;
box-sizing: border-box;
}

.recent-list__scroll {
height: 250px;
overflow: auto;

.recent-list {
display: grid;
grid-template-columns: repeat(6, 1fr);
text-align: center;
font-size: 17px;
padding: 15px 40px;
box-sizing: border-box;
}
}
}
}
}
2 changes: 2 additions & 0 deletions front-end/src/pages/RankingPage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,13 +96,15 @@ function RankingPage() {
rankApiTemplate.nickName = inputRef?.current?.value;
syncKeyWithServer(rankApiTemplate, categoryButtonState, modeButtonState);
const res = await fetchGetRank(rankApiTemplate);
console.log(res.data, 'hihi');
setPlayers(res.data);
};

useEffect(() => {
(async function effect() {
syncKeyWithServer(rankApiTemplate, categoryButtonState, modeButtonState);
const res = await fetchGetRank(rankApiTemplate);
console.log(res.data, 'byeye');
setPlayers(res.data);
})();
}, [categoryButtonState, modeButtonState]);
Expand Down

0 comments on commit cb1a1d1

Please sign in to comment.