GridItem.js 4.91 KB
import { useContext, useEffect, useRef, useState } from "react";
import localforage from "localforage";

import { toYMD, toYMDStr } from "../utils/Dates";

import { CalendarStateContext } from "../pages/Calendar";
import ScheduleItem from "./ScheduleItem";
import axios from "axios";

const GridItem = ({ targetDate }) => {
  const { state: calState, subsObj } = useContext(CalendarStateContext);
  const { month: calMonth } = toYMD(calState.date);
  const { month, date } = toYMD(targetDate);
  const [schedules, setSchedules] = useState();
  const [state, setState] = useState({
    label: "",
    startTime: "",
    endTime: "",
    description: "",
    url: "",
    type: "assignment",
    subjectID: 0,
  });

  useEffect(() => {
    async function loadScheduleItems() {
      const params = {
        userID: await localforage.getItem("userID"),
        date: toYMDStr(targetDate, "-"),
        day: targetDate.getDay(),
      };
      const { data: scdate } = await axios.get(
        "http://3.34.173.161:3001/db/schedules_date",
        { params }
      );
      const { data: sctime } = await axios.get(
        "http://3.34.173.161:3001/db/schedules_time",
        { params }
      );
      const { data: scrpeat } = await axios.get(
        "http://3.34.173.161:3001/db/schedules_repeat",
        { params }
      );
      const subs = await localforage.getItem("subjects");
      setState({ ...state, subjectID: subs[0].subjectID });
      setSchedules(scrpeat.concat(scdate, sctime));
    }
    loadScheduleItems();
  }, [targetDate]);

  const handleChangeState = (e) => {
    setState({
      ...state,
      [e.target.name]: e.target.value,
    });
  };

  const finishSchedule = async (table, uid) => {
    for (const i in schedules)
      if (schedules[i].uid === uid) {
        await axios.delete("http://3.34.173.161:3001/db/schedule", {
          data: {
            table,
            uid,
            userID: await localforage.getItem("userID"),
          },
        });
        schedules.splice(i, 1);
        setSchedules(schedules);
      }
  };

  const popupRef = useRef();
  const click = async (e) => {
    if (e.target.classList.contains("gi")) {
      popupRef.current.style.display = "flex";
    } else if (e.target.className === "gipc") {
      popupRef.current.style.display = "none";
    } else if (e.target.className === "gipa") {
      //  (userID, label, subjectID, type, description, url, date)
      const table =
        state.startTime || state.endTime ? "schedules_time" : "schedules_date";
      const { data: sche } = await axios.post(
        "http://3.34.173.161:3001/db/" + table,
        {
          userID: await localforage.getItem("userID"),
          ...state,
          date: toYMDStr(targetDate, "-"),
        }
      );
      setSchedules(schedules.concat(sche));
      popupRef.current.style.display = "none";
    }
  };

  return (
    <div
      className="GridItem gi"
      relative={month - calMonth || null}
      onClick={click}
      scope={calState.scope}
    >
      <span className="date gi">
        {calMonth !== month ? month + "/" + date : date}
      </span>
      {schedules &&
        schedules.map((sche, index) => (
          <ScheduleItem key={index} schedule={sche} finish={finishSchedule} />
        ))}
      <div className="gi_popup" popup="true" ref={popupRef}>
        <span>일정 추가</span>
        <div className="gipd">
          <input
            name="label"
            placeholder="이름"
            value={state.label}
            onChange={handleChangeState}
          />
          <select
            name="subjectID"
            value={state.subjectID}
            onChange={handleChangeState}
          >
            {Object.values(subsObj).map((sub, index) => (
              <option key={index} value={sub.subjectID}>
                {sub.name}
              </option>
            ))}
          </select>
          <select name="type" value={state.type} onChange={handleChangeState}>
            <option value={"assignment"}>E-Campus</option>
            <option value={"zoom"}>Zoom</option>
          </select>
          <input
            name="startTime"
            placeholder="시작 (HH:MM)"
            value={state.startTime}
            onChange={handleChangeState}
          />
          <input
            name="endTime"
            placeholder="종료 (HH:MM)"
            value={state.endTime}
            onChange={handleChangeState}
          />
          <textarea
            name="description"
            placeholder="설명"
            value={state.description}
            onChange={handleChangeState}
          />
          <textarea
            name="url"
            placeholder="링크"
            value={state.url}
            onChange={handleChangeState}
          />
        </div>
        <div className="gip_btn">
          <button className="gipc">취소</button>
          <button className="gipa">추가</button>
        </div>
      </div>
    </div>
  );
};

export default GridItem;