11import { useEffect , useState , useMemo } from "react" ;
2+ import { Views } from "react-big-calendar" ;
23import { useTimetable } from "../../contexts/TimetableContext" ;
3- import type { Semester } from "../../util/types" ;
4+ import { useEvents } from "../../contexts/EventContext" ;
5+ import { useFilter } from "../../contexts/FilterContext" ;
6+ import type {
7+ CalendarEvent ,
8+ Event ,
9+ FetchWeekEventArgs ,
10+ Semester ,
11+ } from "../../util/types" ;
412import { AddClassPanel } from "./AddClassPanel" ;
513import {
614 flattenCoursesToBlocks ,
715 config ,
816} from "../../util/weekly_timetable/layout" ;
17+ import calendarEventMapper from "../../util/Calendar/calendarEventMapper" ;
18+ import { formatDateToYYYYMMDD } from "../../util/Calendar/dateFormatter" ;
919import { TimetableGrid } from "./TimetableGrid" ;
1020import styles from "@styles/Timetable.module.css" ;
1121import { SlArrowLeft } from "react-icons/sl" ;
@@ -38,12 +48,15 @@ export default function TimetablePage() {
3848 // updateCustomCourse,
3949 deleteCourse,
4050 } = useTimetable ( ) ;
51+ const { weekViewData, fetchWeekEvents } = useEvents ( ) ;
52+ const { globalCategory, globalOrg, globalStatus } = useFilter ( ) ;
4153
4254 const [ year , setYear ] = useState < number > ( now . getFullYear ( ) ) ;
4355 const [ semester , setSemester ] = useState < Semester > ( "SPRING" ) ;
4456 const [ tableName , setTableName ] = useState < string > ( "" ) ;
4557 const [ isAddClassPanelOpen , setIsAddClassPanelOpen ] = useState ( false ) ;
4658 const [ isSidebarOpen , setIsSidebarOpen ] = useState ( true ) ;
59+ const [ isTimetableSimplified , setIsTimetableSimplified ] = useState ( false ) ;
4760
4861 useEffect ( ( ) => {
4962 loadTimetable ( year , semester ) ;
@@ -72,12 +85,87 @@ export default function TimetablePage() {
7285 [ visibleCourses ] ,
7386 ) ;
7487
88+ useEffect ( ( ) => {
89+ const today = new Date ( ) ;
90+ const from = new Date ( today ) ;
91+ from . setDate ( from . getDate ( ) - from . getDay ( ) ) ;
92+
93+ const to = new Date ( from ) ;
94+ to . setDate ( to . getDate ( ) + 6 ) ;
95+
96+ const params : FetchWeekEventArgs = {
97+ from : formatDateToYYYYMMDD ( from ) ,
98+ to : formatDateToYYYYMMDD ( to ) ,
99+ } ;
100+
101+ if ( globalCategory ) params . eventTypeId = globalCategory . map ( ( g ) => g . id ) ;
102+ if ( globalOrg ) params . orgId = globalOrg . map ( ( g ) => g . id ) ;
103+ if ( globalStatus ) params . statusId = globalStatus . map ( ( g ) => g . id ) ;
104+
105+ void fetchWeekEvents ( params ) ;
106+ } , [ fetchWeekEvents , globalCategory , globalOrg , globalStatus ] ) ;
107+
108+ const weekCalendarEvents = useMemo ( ( ) => {
109+ const weekStart = new Date ( ) ;
110+ weekStart . setHours ( 0 , 0 , 0 , 0 ) ;
111+ weekStart . setDate ( weekStart . getDate ( ) - weekStart . getDay ( ) ) ;
112+
113+ const weekEnd = new Date ( weekStart ) ;
114+ weekEnd . setDate ( weekEnd . getDate ( ) + 6 ) ;
115+ weekEnd . setHours ( 23 , 59 , 59 , 999 ) ;
116+
117+ const rawWeekEvents = Object . values ( weekViewData ?. byDate || { } ) . flatMap (
118+ ( bucket ) => bucket . events ,
119+ ) ;
120+ const uniqueWeekEvents = Array . from (
121+ new Map ( rawWeekEvents . map ( ( event : Event ) => [ event . id , event ] ) ) . values ( ) ,
122+ ) ;
123+
124+ return uniqueWeekEvents
125+ . map ( ( event ) => calendarEventMapper ( event , Views . WEEK ) as CalendarEvent )
126+ . filter (
127+ ( calendarEvent ) =>
128+ calendarEvent . start >= weekStart && calendarEvent . end <= weekEnd ,
129+ )
130+ . map ( ( calendarEvent ) => {
131+ const sameMinute =
132+ Math . floor ( calendarEvent . start . getTime ( ) / 60000 ) ===
133+ Math . floor ( calendarEvent . end . getTime ( ) / 60000 ) ;
134+ const startDay = new Date (
135+ calendarEvent . start . getFullYear ( ) ,
136+ calendarEvent . start . getMonth ( ) ,
137+ calendarEvent . start . getDate ( ) ,
138+ ) ;
139+ const endDay = new Date (
140+ calendarEvent . end . getFullYear ( ) ,
141+ calendarEvent . end . getMonth ( ) ,
142+ calendarEvent . end . getDate ( ) ,
143+ ) ;
144+ const differentDate =
145+ startDay . getFullYear ( ) !== endDay . getFullYear ( ) ||
146+ startDay . getMonth ( ) !== endDay . getMonth ( ) ||
147+ startDay . getDate ( ) !== endDay . getDate ( ) ;
148+
149+ return {
150+ ...calendarEvent ,
151+ allDay : Boolean ( calendarEvent . allDay ) || differentDate || sameMinute ,
152+ } ;
153+ } )
154+ . filter (
155+ ( calendarEvent ) =>
156+ calendarEvent . resource . isPeriodEvent === false &&
157+ calendarEvent . allDay === false ,
158+ ) ;
159+ } , [ weekViewData ] ) ;
160+
75161 if ( isLoading ) return < div > 로딩 중...</ div > ;
76162
77163 return (
78164 < div
79165 className = { `${ styles . page } ${
80- isAddClassPanelOpen ? styles . AddClassPanelOpen : styles . AddClassPanelClosed
166+ isAddClassPanelOpen
167+ ? styles . AddClassPanelOpen
168+ : styles . AddClassPanelClosed
81169 } ${ isSidebarOpen ? styles . sidebarOpen : styles . sidebarClosed } `}
82170 >
83171 < TimeTableSidebar
@@ -104,6 +192,8 @@ export default function TimetablePage() {
104192 SEMESTER_LABEL = { semesters }
105193 onSemesterChange = { setSemester }
106194 onYearChange = { setYear }
195+ isToggleOn = { isTimetableSimplified }
196+ onToggleChange = { setIsTimetableSimplified }
107197 years = { years }
108198 />
109199
@@ -123,6 +213,8 @@ export default function TimetablePage() {
123213 config = { config }
124214 toBlocks = { flattenCoursesToBlocks }
125215 onRemoveBlock = { deleteCourse }
216+ isSimplified = { isTimetableSimplified }
217+ weekEvents = { isTimetableSimplified ? weekCalendarEvents : [ ] }
126218 />
127219 ) }
128220 </ main >
0 commit comments