주요 기능 | 축구 다이어리 - itsyuna/Foot-Salon GitHub Wiki
Redux Toolkit, Thunk를 사용하여 Data, Store, Module 관리
Firebase와 연동하여 Data 관리
- 최신순/오래된 순
- 경기 결과 (Lose/Draw/Win)
- K리그/해외 축구
- 달마다 리스트 분류
- 응원 경기 수, 경기 결과, 집관/직관
utils/emotion.ts
export const emotionList = [
{
emotionId: 1,
emotionImage: process.env.PUBLIC_URL + `/assets/icons/emotion-1.svg`,
emotionDescription: "lost",
},
{
emotionId: 2,
emotionImage: process.env.PUBLIC_URL + `/assets/icons/emotion-2.svg`,
emotionDescription: "draw",
},
{
emotionId: 3,
emotionImage: process.env.PUBLIC_URL + `/assets/icons/emotion-3.svg`,
emotionDescription: "win",
},
];
StatEditor.tsx
const StatEditor = ({ headText, isEdit }: StatEditorProps) => {
...
// Default emotion icon은 draw(2)로 설정
const [emotion, setEmotion] = useState(2);
// emotion icon 클릭 시, 해당 emotion id가 emotion state에 저장됨
const emotionClickHandler = (emotion: number) => {
setEmotion(emotion);
};
return (
...
<section>
<StatItemName>
<h4>승부 결과를 체크해주세요!</h4>
</StatItemName>
<EmotionItemWrapper>
// 따로 uilts 폴더에 만든 emotionList를 import해서 emotion icon으로 보여주고,
// 선택한 emotion icon을 활성화하기 위해 isSelected props로 background style 변경
{emotionList.map((item) => (
<EmotionItem
key={item.emotionId}
onClick={emotionClickHandler}
isSelected={item.emotionId === emotion}
{...item}
/>
))}
</EmotionItemWrapper>
</section>
...
EmotionItem.tsx
const EmotionBox = styled.div<{ isSelected: boolean }>`
...
// 선택한 emotion icon 활성화
${({ isSelected }) =>
isSelected
? css`
background-color: #b6e2a1;
color: white;
`
: css`
background-color: #f1f7e7;
`}
`
...
return (
<EmotionBox isSelected={isSelected} onClick={emotionHandler}>
<EmotionImage src={emotionImage} alt="Emotion icon" />
<span>{emotionDescription}</span>
</EmotionBox>
);
Statistics.tsx
const matchResult = {
lost: 0,
draw: 0,
win: 0,
};
const watchOption = {
home: 0,
stadium: 0,
};
const Statistics = ({ myStat }: { myStat: StatListItems[] }) => {
myStat.forEach((item) => {
// 경기 결과 저장
if (item.stat.matchResult === 1) matchResult.lost++;
else if (item.stat.matchResult === 2) matchResult.draw++;
else matchResult.win++;
});
let countMatchResult = "";
// 경기 결과 내림차순 저장
const sortMatchResult = Object.entries(matchResult).sort(
([, a], [, b]) => b - a
);
// 번역된 통계로 나타내기 위해서 Map에서 꺼내씀
let matchResultMap = new Map();
matchResultMap.set("lost", "진");
matchResultMap.set("draw", "비긴");
matchResultMap.set("win", "이긴");
// 통계 결과
if (
matchResult.lost === matchResult.draw &&
matchResult.draw === matchResult.win
) {
countMatchResult = "승,무,패 골고루 가져왔어요!";
} else if (sortMatchResult[0][1] === sortMatchResult[1][1]) {
countMatchResult = `'${matchResultMap.get(
sortMatchResult[0][0]
)}+${matchResultMap.get(sortMatchResult[1][0])}' 경기가 많았어요!`;
} else
countMatchResult = `'${matchResultMap.get(
sortMatchResult[0][0]
)}' 경기가 많았어요!`;
myStat.forEach((item) => {
// 집관,직관 저장
if (item.stat.watchOption === "집관 🏡") watchOption.home++;
else watchOption.stadium++;
});
let countWatchOption = "";
// 집관,직관 내림차순 저장
const sortWatchOption = Object.entries(watchOption).sort(
([, a], [, b]) => b - a
);
// 번역된 통계로 나타내기 위해서 Map에서 꺼내씀
let watchOptionMap = new Map();
watchOptionMap.set("home", "집관");
watchOptionMap.set("stadium", "직관");
// 통계 결과
if (sortWatchOption[0][1] === sortWatchOption[1][1]) {
countWatchOption = `'${watchOptionMap.get(
sortWatchOption[0][0]
)}+${watchOptionMap.get(sortWatchOption[1][0])}'을 똑같이 했어요!`;
} else
countWatchOption = `'${watchOptionMap.get(
sortWatchOption[0][0]
)}'을 더 많이 했어요!`;
Stats page

Stat 쌓기

Stat 상세 보기

Stat 수정

Stat이 없을 시

에러 처리
🔻 해당 번호의 Stat이 없을 시