[react-github-calendar, GithubChart] Github 잔디 라이브러리 커스텀

2023. 1. 3. 16:48Next.js

728x90
반응형

GitHub 잔디 라이브러리 종류

깃허브 잔디를 가져오는 라이브러리 두가지를 사용해봤다.

  • Github Chart
    잔디 색상 테마를 지정할 수 있지만, 이외의 커스텀은 불가능하다.
  • GitHub Contributions Calendar
    기간 및 잔디 크기, 라벨 등 세세한 커스텀이 가능하다.

 

[Github Chart]

1. 잔디 가져오기

img 태그의 src 속성값으로 https://ghchart.rshah.org/깃허브_아이디만 입력해주면 된다. 완전 간단하다👍🏾

<img src="https://ghchart.rshah.org/깃허브_아이디" />

 

2. 색상 테마 지정하기

깃허브 아이디 앞에 HEX 색상 코드를 추가해주면 된다.

<img src="https://ghchart.rshah.org/HEX_색상_코드/깃허브_아이디" />

// 예시
<img src="https://ghchart.rshah.org/333333/e-juhee" />

 

[GitHub Contributions Calendar API]

1. 잔디 가져오기

라이브러리 설치 후 import해서 사용한다.

// 사용할 프로젝트의 터미널에서 입력
yarn add react-github-calendar
import GitHubCalendar from 'react-github-calendar';

...

<GitHubCalendar username="깃허브_아이디" />

 

2. 커스텀: label, 요일, 사이즈

[DOCS]
DOCS에 변경할 수 있는 내용이 명시되어 있다.

 <GitHubCalendar
    // 깃허브 계정
   username={props.githubId}

   // 좌측 하단의 메시지
   labels={{
            totalCount: "Learn how we count contributions",
           }}

   // 좌측 요일 표시
   showWeekdayLabels

   // 사이즈 조정
   blockSize={13}
   style={{
    height: "14.4rem",
      width: "72rem",
        marginLeft: "2.5rem",
  }}
  />

 

3. Tooltip 추가

ReactTooltip을 설치하고 import해서 사용한다.


그냥 추가하면 Next.js 환경에서는 Prop dangerouslySetInnerHTML did not match. 에러가 발생한다.

 

GitHubCalendar를 브라우저가 렌더링 되고 나서 불러올 수 있도록 isMouted state를 만들어서 사용했다.

 

import GitHubCalendar from "react-github-calendar";
import ReactTooltip from "react-tooltip";

...
  // 렌더링 전에 react-tooltip을 불러오지 않게 하기 위해 사용
  const [isMounted, setIsMounted] = useState(false);
  useEffect(() => {
    setIsMounted(true);
  }, []);

...

return (
  {isMounted && (
      <GitHubCalendar username={props.githubId}>
        <ReactTooltip html />
      </GitHubCalendar>
   )}
 );

 

4. 모바일 버전: 노출 기간 지정

모바일 환경에서는 12개월을 보여주기 적합하지 않아, 5개월만 노출하도록 transformData 속성을 추가했다.

  // type
  interface Day {
    date: string;
    count: number;
    level: 0 | 1 | 2 | 3 | 4;
  }

  // 최근 5개월만 return하는 함수
  const selectLastHalfYear = (contributions: Day[]) => {

    // 현재 연/월
    const currentYear = new Date().getFullYear();
    const currentMonth = new Date().getMonth();

    // 노출할 기간(달)
    const shownMonths = 5;

    return contributions.filter((day: Day) => {
      const date = new Date(day.date);
      const monthOfDay = date.getMonth();

      // 현재 날짜가 6월~12월 사이인 경우
      if (currentMonth >= 5)
        return (
          date.getFullYear() === currentYear &&
          monthOfDay > currentMonth - shownMonths &&
          monthOfDay <= currentMonth
        );

      // 현재 날짜가 1월~5월인 경우
      return (
        // 올해
        (date.getFullYear() === currentYear && monthOfDay <= currentMonth) ||
        // 작년
        (date.getFullYear() === currentYear - 1 &&
          monthOfDay > currentMonth + 11 - shownMonths)
      );
    });
  };

...

<GitHubCalendar
  username={props.githubId}
  blockSize={12}
  transformData={selectLastHalfYear}
>
  <ReactTooltip html />
</GitHubCalendar>

 

5. 예외 처리: 존재하지 않는 아이디

사용자에게 깃허브 아이디를 입력받아 보여주는 경우, 존재하지 않는 아이디에 대한 예외 처리가 필요하다.

 

👇🏻 아이디가 존재하지 않을 경우 아래와 같은 화면이 노출된다.

Unable to fetch contribution data. See console.

 

이 경우에 다른 화면을 띄워주기 위해 error가 나는 상황을 감지할 방법이 필요했다.

 

이 라이브러리는 별도로 error 핸들링 방법을 제공하지 않아서,
라이브러리를 호출하기 전에 get 요청을 먼저 보내보고( gitValidation 함수 ), 결과에 따라서 라이브러리를 호출할 수 있도록 별도의 state( gitResult )에 요청 결과를 담아서 활용했다.

 

이 과정에서 시간이 소요되므로, 로딩이 완료된 후에 화면에 렌더되도록 gitResultLoading state를 활용했다.

  useEffect(() => {
    gitValidation();
  }, []);

  // 깃허브 아이디가 유효할 경우에만 true
  const [gitResult, setGitResult] = useState(false);

  // 깃허브 아이디 조회가 완료되면 false로 변경
  const [gitResultLoading, setGitResultLoading] = useState(true);

  /**
   * 깃허브 아이디가 유효한지 확인하는 함수
   */
  const gitValidation = async () => {
    try {
      await axios.get(
        `https://github-contributions-api.jogruber.de/v4/${props.githubId}?y=last`
      );
      setGitResult(true);
    } catch (err) {
      setGitResult(false);
    }
    setGitResultLoading(false);
  };

...

  !gitResultLoading &&
   (gitResult ? (
              <GitHubCalendar
                username={props.githubId}
                showWeekdayLabels
                blockSize={13}
                style={{
                  height: "14.4rem",
                  width: "72rem",
                  marginLeft: "2.5rem",
                }}
              >
                <ReactTooltip html />
              </GitHubCalendar>
        ) :  (

          {/* 깃허브 아이디가 존재하지 않은 경우 */}
            <NoGithub>
              <p>올바른 깃허브 아이디를 등록해주세요.</p>
              <button
                onClick={() =>
                  router.push(`/mypage/dashboard/setting/${props?.userId}`)
                }
              >
                계정 등록하기
              </button>
            </NoGithub>
          </>
        ) 

gitResult가 true로 바뀐 경우에만 <GitHubCalendar/>를 리턴한다.

 

👇🏻 gitResult가 false인 경우

 

728x90
반응형