학교 시간표를 구축하고 구글 달력 API를 지원 API로 사용한다.

도전은 우리가 학교에서 사용하는 전통적인 학교 달력을 디지털화하고 구글 달력 API를 지원 API로 사용하는 것이다.내 이해에서 구글 달력에서 수업을 받아 인터넷 응용 프로그램에 보여주는 것을 의미한다.
이를 위해, 나는 두 가지 방법을 채택하기로 결정했다.
  • 방법 1.처음부터 전체 시간표 구조를 구축한 다음에 함수를 작성하여 데이터를 얻고 표시합니다.
  • 방법2.비구조화된 구글 달력 데이터를 처리하고 이벤트/과정을 표시할 수 있는 패키지 구성 요소를 찾습니다.
  • 방법

    워크플로


    Use styled-components to build a reusable TableColumn component that will take in props and inside it, use those props to fetch data dynamically from a json file.
    
    src 폴더에서, 나는 데이터라는 폴더를 만들었고, 그 중에서subjectData라는 파일을 만들었다.json, 이것이 바로 나의 데이터입니다.
    TableColumns 구성 요소의 경우 이것이 바로 구축입니다.내가 스타일화된 구성 요소를 선택한 것은 원소를 제어해야 하기 때문이다. 이것은 내가 많은 코드를 작성할 필요가 없다는 것을 의미한다. 왜냐하면 나는 자신의 의사에 따라 도구를 전달할 수 있기 때문이다.
    import React from "react";
    import styled from "styled-components";
    const data = require("../data/subjectData.json");
    
    const MainDiv = styled.div`
      height: 30em;
      width: 11.6em;
      border-right: 1px solid black;
      border-bottom: 1px solid black;
    `;
    
    const ItemDiv = styled.div`
      height: ${(props) => (props.subject ? "5em" : "2.5em")};
      width: ${(props) => (props.half ? "50%" : "100%")};
      display: flex;
      align-items: center;
      justify-content: center;
      border-bottom: 1px solid black;
    `;
    
    const ClassTitleDiv = styled.div`
      display: flex;
      flex-flow: row nowrap;
    `;
    
    const MainClassColumnDiv = styled.div`
      display: flex;
      flex-flow: row nowrap;
      height: 25em;
      width: 100%;
    `;
    
    const ClassColumnDiv = styled.div`
      height: 100%;
      width: 50%;
      background-color: ${(props) => (props.col ? "#f1f3f8" : "#d6e0f0")};
      display: flex;
      flex-flow: column nowrap;
      align-items: center;
      justify-content: center;
    `;
    
    function TableColumn({ title, lesson }) {
      return (
        <MainDiv>
          <ItemDiv>{title}</ItemDiv>
          <ClassTitleDiv>
            <ItemDiv half>3N</ItemDiv>
            <ItemDiv half>3S</ItemDiv>
          </ClassTitleDiv>
          <MainClassColumnDiv>
            <ClassColumnDiv col>
              {data.subject[lesson]["3N"].map((sub) => {
                return (
                  <ItemDiv half subject>
                    {sub.subject}
                  </ItemDiv>
                );
              })}
            </ClassColumnDiv>
            <ClassColumnDiv>
              {data.subject[lesson]["3S"].map((sub) => {
                return (
                  <ItemDiv half subject>
                    {sub.subject}
                  </ItemDiv>
                );
              })}
            </ClassColumnDiv>
          </MainClassColumnDiv>
        </MainDiv>
      );
    }
    
    export default TableColumn;
    
    이 TableColumn 구성 요소는 3N 클래스와 3S 클래스로 수업마다 그려져 있습니다.각 구성 요소는 두 종류의 수업을 대표한다.
    전체 시간표를 보여주는 홈 페이지에 외부 시간표 구조를 설정한 다음 TableColumn을 하위 구성 요소로 전달합니다.
    import React from "react";
    import styled from "styled-components";
    import TableColumn from "../components/TableColumn";
    
    const MainDiv = styled.div`
      height: 100vh;
      display: flex;
      flex-flow: column;
      align-items: center;
    `;
    
    const Title = styled.h3`
      font-size: 2em;
      font-weight: 800;
      margin-top: 0.2em;
    `;
    
    const MainTableDiv = styled.div`
      height: auto;
      width: auto;
      display: flex;
      flex-flow: row nowrap;
    `;
    
    const DayOfWeekDiv = styled.div`
      height: 25em;
      width: 8em;
      padding-top: 5em;
      border-right: 1px solid black;
      border-bottom: 1px solid black;
    `;
    
    const Day = styled.div`
      height: 5em;
      width: 100%;
      display: flex;
      align-items: center;
      justify-content: center;
      font-weight: 500;
    `;
    
    function HomePage() {
      const days = ["Mon", "Tue", "Wed", "Thur", "Fri"];
      return (
        <MainDiv>
          <Title>
            <u>School TimeTable</u>
          </Title>
          <MainTableDiv>
            <DayOfWeekDiv>
              {days.map((day) => {
                return <Day>{day}</Day>;
              })}
            </DayOfWeekDiv>
            <TableColumn title={"8am - 9am"} lesson={"lesson1"} />
            <TableColumn title={"10am - 11am"} lesson={"lesson2"} />
            <TableColumn title={"11:30am - 12:45pm"} lesson={"lesson3"} />
            <TableColumn title={"1:30pm - 2:30pm"} lesson={"lesson4"} />
            <TableColumn title={"3pm - 4pm"} lesson={"lesson5"} />
          </MainTableDiv>
        </MainDiv>
      );
    }
    
    export default HomePage;
    
    JSON 로더를 사용하기 위해 패키지 설정을 설정했습니다.

    테스트


    For the tests, I did not have much to test but I had to ensure that the TableColumn component's structure remains intact and so I set up snapshot test.
    
    import React from "react";
    import renderer from "react-test-renderer";
    import TableColumn from "./components/TableColumn";
    
    test("renders correctly the table columns", () => {
      const title = "Titles";
      const tree = renderer
        .create(<TableColumn title={title} lesson={"lesson5"} />)
        .toJSON();
      expect(tree).toMatchSnapshot();
    });
    
    

    CI/CD


    이 부분은 매번 나를 흥분시킨다.이 웹 앱에 대해 저는 간단함을 유지하고 싶습니다. 그래서 저는 지속적인 통합과 배치 구조를 유지했습니다. 매우 간단합니다.
    하나 만들었어요.github 폴더에 두 개의 파일을 포함하는 작업 흐름 폴더:integrate를 추가했습니다.CI 및 배포를 처리하는 ymlCD를 처리하는 yml입니다.
    통합yml 회사
    name: React Continuous Integration
    
    on:
      pull_request:
        branches: [master]
    
    jobs:
      test_pull_request:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v2
          - run: yarn install
          - run: yarn test -u
          - run: yarn test
          - run: yarn build
    
    
    이것은 단지 드래그 요청을 만들 때 테스트를 실행할 뿐입니다.
    배치yml 회사
    name: Firebase Continuous Deployment
    
    on:
      push:
        branches: [master]
    
    jobs:
        deploy:
          runs-on: ubuntu-latest
          steps:
            - uses: actions/checkout@master
            - run: yarn install
            - run: yarn build
            - uses: w9jds/firebase-action@master
              with:
                args: deploy --only hosting
              env:
                FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }}
    
    변경 사항이 발견되면 마스터에 서명합니다.최적화된 구축을 만들기 위해 필요한 모든 명령을 실행합니다.그 다음에 Firebase action이라는 Github 동작 프로그램을 사용하여 모든 Firebase 명령을 처리합니다.그리고 이 웹 응용 프로그램은 Firebase에 성공적으로 위탁 관리되었다.
    이런 방법은 구글 캘린더 API를 사용하지 않았다.주요 원인은 달력 데이터를 내 구성 요소 구조에서 정확하게 사용할 수 있는 데이터로 구성하는 데 시간이 필요하다는 것을 깨달았기 때문이다.나는 내가 어떻게 자신의 완전한 맞춤형 스케줄러를 구축하는지 알기 전에 하나의 작업의 원형이 더욱 의미가 있을 것이라고 생각한다.
    결과는 다음과 같다는 얘기다.
    결과

    View Live
    The Github Repository
    방법 2

    워크플로


    이런 방법에서, 나는 이미 미리 구축된 스케줄러 구성 요소를 찾기로 결정했다.아주 오랜 시간이 지나서 나는 찾았다 DevExtreme Scheduler.
    이것은 내가 데이터를 미리 구축된 데이터 저장소에 전달할 수 있도록 한다. 이 저장소는 모든 데이터를 이해하고 스케줄러 구성 요소에 전달할 수 있다.
    지금 나는 구글 달력에서 나의 활동 데이터를 얻기만 하면 된다.이를 위해서는 GCP 프로젝트의 구글 제품 키와 달력 ID가 필요합니다. Google Calendar API reference
    이것은 하나의 구성 요소가 전체 웹 응용 프로그램을 실행할 수 있다는 것을 의미한다.
    import React, { Component } from "react";
    // prebuilt table component
    import Scheduler from "devextreme-react/scheduler";
    // data handler
    import CustomStore from "devextreme/data/custom_store";
    import "whatwg-fetch";
    
    // function to fetch the events from the calendar
    function getLessons(_, requestOptions) {
      const PUBLIC_KEY = process.env.REACT_APP_GOOGLE_PUBLIC_KEY,
        CALENDAR_ID = process.env.REACT_APP_CALENDAR_ID;
      const lessonsUrl = [
        "https://www.googleapis.com/calendar/v3/calendars/",
        CALENDAR_ID,
        "/events?key=",
        PUBLIC_KEY,
      ].join("");
    
      return fetch(lessonsUrl, requestOptions)
        .then((response) => response.json())
        .then((data) => data.items);
    }
    
    // data handler
    const dataSource = new CustomStore({
      load: (options) => getLessons(options, { showDeleted: false }),
    });
    
    // scheduler preferences
    const currentDate = new Date(2020, 8, 21);
    const views = ["day", "workWeek"];
    
    class App extends Component {
      render() {
        return (
          <>
            <div className="title">
              <h3>
                <u>3N TimeTable</u>
              </h3>
            </div>
            <Scheduler
              dataSource={dataSource}
              views={views}
              defaultCurrentView="workWeek"
              defaultCurrentDate={currentDate}
              height={500}
              startDayHour={7}
              endDayHour={16}
              editing={false}
              showAllDayPanel={false}
              startDateExpr="start.dateTime"
              endDateExpr="end.dateTime"
              textExpr="summary"
              timeZone="Africa/Nairobi"
            />
          </>
        );
      }
    }
    
    export default App;
    
    스케줄러 구성 요소에서 편집 설정은false입니다. 만약 관리 페이지가 있다면, 같은 스케줄러 구조만 사용하고 편집 속성을true로 설정하여 웹 응용 프로그램을 통해 이벤트 편집을 할 수 있도록 합니다.
    테스트에 대해 나는 이런 방법에 관한 어떠한 정보도 없다.200의 결과 코드를 확보하기 위해 이 함수를 테스트하겠지만.
    이런 방법에 대해, 나는rouse가 존재하지 않도록 404 페이지를 추가했다.

    CI/CD


    나는 아무런 테스트도 하지 않았기 때문에 CI를 설정하지 않았다.
    CD에 대해 나는 첫 번째 방법과 같은 간소화 구조를 채택했다.그러나 이것에 대해 나는 환경 변수에 넣었기 때문에 키 (구글 키와 달력 ID) 를 전달해야 한다.
    name: Firebase Continuous Deployment.
    
    on:
      push:
        branches: [master]
    
    jobs:
      deploy:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@master
          - run: yarn install
          - run: yarn build
            env:
              REACT_APP_GOOGLE_PUBLIC_KEY: ${{ secrets.REACT_APP_GOOGLE_PUBLIC_KEY }}
              REACT_APP_CALENDAR_ID: ${{ secrets.REACT_APP_CALENDAR_ID}}
          - uses: w9jds/firebase-action@master
            with:
              args: deploy --only hosting
            env:
              FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }}
    
    
    이 비밀들은 GitHub repo의 settings then secrets에 추가되어 새로운 비밀을 만듭니다.
    결과

    View Live
    The Github Repository
    그렇습니다.이것이 바로 내가 도전에 대처하는 방식이다.
    고마워요!

    좋은 웹페이지 즐겨찾기