Calendar.js 2.79 KB
import React, { useEffect, useReducer, useState } from "react";
import { useNavigate, Route, Routes } from "react-router-dom";
import localforage from "localforage";
import axios from "axios";

import Month from "../components/Month";
import Header from "../components/Header";
import Side from "../components/Side";
import Week from "../components/Week";
import Day from "components/Day";
import "../styles/Calendar.css";
import "../styles/Header.css";

export const CalendarStateContext = React.createContext();

const render = (subsObj, args) => {
  let sub;
  switch (args.type) {
    case "CHECKED":
      sub = subsObj[args.subjectID];
      sub.status = !sub.status;
      axios.put(
        `http://${process.env.REACT_APP_SERVER_IP}:3001/db/user-subject/check`,
        {
          userID: sub.userID,
          subjectID: args.subjectID,
          status: +sub.status,
        }
      );
      return { ...subsObj, [args.subjectID]: sub };
    case "MODIFY":
      sub = subsObj[args.subjectID];
      sub.nickname = args.nickname;
      sub.color = args.color;
      axios.put(
        `http://${process.env.REACT_APP_SERVER_IP}:3001/db/user-subject/modify`,
        {
          userID: sub.userID,
          subjectID: args.subjectID,
          nickname: sub.nickname,
          color: sub.color,
        }
      );
      return { ...subsObj, [args.subjectID]: sub };
    case "INIT":
      return args.subsObj;
    default:
      return subsObj;
  }
};

const Calendar = () => {
  // console.log("visit Calendar");

  const [state, setState] = useState({
    scope: "month",
    date: new Date(),
  });
  const [subsObj, dispatch] = useReducer(render, {});

  const navigate = useNavigate();
  useEffect(() => {
    async function onMount() {
      if (!(await localforage.getItem("session"))) return navigate("/login");
      // get user's subjects
      const userID = await localforage.getItem("userID");
      const { data: subjects } = await axios.get(
        `http://${process.env.REACT_APP_SERVER_IP}:3001/db/user-subject`,
        { params: { userID } }
      );
      await localforage.setItem("subjects", subjects);
      let tsubsObj = {};
      for (const sub of subjects) {
        tsubsObj[sub.subjectID] = sub;
      }
      dispatch({ type: "INIT", subsObj: tsubsObj });
    }
    onMount();
  }, [navigate]);

  return (
    <CalendarStateContext.Provider
      value={{ state, setState, subsObj, dispatch }}
    >
      <div className="Calendar">
        <Header />
        <div className="content">
          <Side />
          <Routes>
            <Route path="/month/*" element={<Month />} />
            <Route path="/week/*" element={<Week />} />
            <Route path="/day/*" element={<Day />} />
          </Routes>
        </div>
      </div>
    </CalendarStateContext.Provider>
  );
};

export default Calendar;