주요 기능 | 축구 다이어리 - itsyuna/Foot-Salon GitHub Wiki

Stats

Redux Toolkit, Thunk를 사용하여 Data, Store, Module 관리

Firebase와 연동하여 Data 관리


✔️ 다이어리 작성/읽기/업데이트/삭제

✔️ K리그/해외 축구, 집관/직관 분류

✔️ 경기 결과 감정 이모티콘 사용(Lose/Draw/Win)

✔️ Filter

  • 최신순/오래된 순
  • 경기 결과 (Lose/Draw/Win)
  • K리그/해외 축구
  • 달마다 리스트 분류

✔️ 달마다 통계 분석

  • 응원 경기 수, 경기 결과, 집관/직관

💻 Code

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]
    )}'을 더 많이 했어요!`;

🖥 View

Stats page Stats page
Stat 쌓기 New Stat
Stat 상세 보기 Stat 상세 보기
Stat 수정 Stat 수정
Stat이 없을 시 Stat 데이터가 없을 시
에러 처리

🔻 해당 번호의 Stat이 없을 시
해당 게시글이 없을 시

⚠️ **GitHub.com Fallback** ⚠️