Skip to content
Snippets Groups Projects
CalendarWeek.jsx 5.08 KiB
Newer Older
  • Learn to ignore specific revisions
  • import React, { useState, useEffect } from "react";
    
    import "../styles/CalendarWeek.css";
    
    
    const days = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
    
    const CalendarWeek = ({
      participants,
      startDate,
      endDate,
      maxParticipants,
      hoveredInfo,
      setHoveredInfo,
    }) => {
      const [currentWeekIndex, setCurrentWeekIndex] = useState(0);
      const [weeks, setWeeks] = useState([]);
    
      const [schedule, setSchedule] = useState({});
    
    
      const handlePrevWeek = () => {
        setCurrentWeekIndex(Math.max(0, currentWeekIndex - 1));
      };
    
      const handleNextWeek = () => {
        setCurrentWeekIndex(Math.min(weeks.length - 1, currentWeekIndex + 1));
      };
    
      useEffect(() => {
        const start = new Date(startDate);
        start.setDate(
          start.getDate() - (start.getDay() === 0 ? 6 : start.getDay() - 1)
        );
        const end = new Date(endDate);
    
        let weeksTemp = [];
        while (start <= end) {
          const weekStart = new Date(start);
          const weekDates = Array.from({ length: 7 }).map((_, index) => {
            const date = new Date(weekStart);
            date.setDate(date.getDate() + index);
            return date;
    
    
          weeksTemp.push(weekDates);
          start.setDate(start.getDate() + 7);
    
        setWeeks(weeksTemp);
    
        let newSchedule = {};
        participants.forEach((participant) => {
          participant.availableSchedules.forEach(
            ({ availableDate, availableTimes }) => {
              const date = new Date(availableDate);
              availableTimes.forEach((time) => {
                const hour = Math.floor(time / 2);
                const minute = (time % 2) * 30;
                const timeString = `${hour.toString().padStart(2, "0")}:${minute
                  .toString()
                  .padStart(2, "0")}`;
                const dateString = `${date.getFullYear()}-${(date.getMonth() + 1)
                  .toString()
                  .padStart(2, "0")}-${date.getDate().toString().padStart(2, "0")}`;
                if (!newSchedule[dateString]) {
                  newSchedule[dateString] = [];
                }
                newSchedule[dateString].push({
                  time: timeString,
                  name: participant.name,
                });
              });
            }
          );
        });
        setSchedule(newSchedule);
      }, [participants, startDate, endDate]);
    
      const calculateOpacity = (dateString, timeString) => {
        const availableCount =
          schedule[dateString]?.filter((s) => s.time === timeString).length || 0;
        return 100 - (availableCount / maxParticipants) * 100;
      };
    
      const handleMouseEnter = (dateString, timeString) => {
        const availableParticipants =
          schedule[dateString]
            ?.filter((s) => s.time === timeString)
            .map((s) => s.name) || [];
        setHoveredInfo({
          date: dateString,
          time: timeString,
          participants: availableParticipants,
        });
    
      const handleMouseLeave = () => {
        setHoveredInfo(null);
      };
    
      const weekDates = weeks[currentWeekIndex] || [];
    
    
    준현 강's avatar
    준현 강 committed
        <div className="wrap">
          <div className="button-container">
            <button onClick={handlePrevWeek} disabled={currentWeekIndex === 0}>
              Prev Week
            </button>
            <button
              onClick={handleNextWeek}
              disabled={currentWeekIndex === weeks.length - 1}
            >
              Next Week
            </button>
          </div>
    
          <table className="calendar-container">
            <thead>
              <tr>
                <th>Time</th>
                {weekDates.map((date) => (
                  <th key={date.toISOString()}>
                    {date.getMonth() + 1}/{date.getDate()} ({days[date.getDay()]})
                  </th>
    
            </thead>
            <tbody>
              {[...Array(48).keys()].map((timeSlot) => {
                const hour = Math.floor(timeSlot / 2);
                const minute = (timeSlot % 2) * 30;
                return (
                  <tr key={timeSlot}>
                    <td>
                      {hour.toString().padStart(2, "0") +
                        ":" +
                        minute.toString().padStart(2, "0")}
                    </td>
                    {weekDates.map((date) => {
                      const dateString = `${date.getFullYear()}-${(
                        date.getMonth() + 1
                      )
                        .toString()
                        .padStart(2, "0")}-${date
                        .getDate()
                        .toString()
                        .padStart(2, "0")}`;
                      const timeString = `${hour
                        .toString()
                        .padStart(2, "0")}:${minute.toString().padStart(2, "0")}`;
                      const opacity = calculateOpacity(dateString, timeString);
                      const cellStyle = { opacity: `${opacity}%` };
                      return (
                        <td
                          key={`${date.toISOString()}-${timeString}`}
                          style={cellStyle}
                          onMouseEnter={() =>
                            handleMouseEnter(dateString, timeString)
                          }
                          onMouseLeave={handleMouseLeave}
                        />
                      );
                    })}
                  </tr>
                );
              })}
            </tbody>
          </table>
        </div>
    
      );
    };
    
    export default CalendarWeek;