Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
182 changes: 0 additions & 182 deletions src/components/sections/timetable/timetableandinfos/ExamSubSection.jsx

This file was deleted.

121 changes: 121 additions & 0 deletions src/components/sections/timetable/timetableandinfos/ExamSubSection.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import React, { useState } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { useTranslation } from 'react-i18next';

import { appBoundClassNames as classNames } from '@/common/boundClassNames';

import Scroller from '../../../Scroller';

import { setMultipleFocus, clearMultipleFocus } from '@/redux/actions/timetable/lectureFocus';
import { getOverallLectures, isSingleFocused } from '@/utils/lectureUtils';
import { getTimeStr } from '@/utils/examtimeUtils';
import { getDayStr } from '@/utils/timeUtils';

import { LectureFocusFrom } from '@/shapes/enum';
import { useTranslatedString } from '@/hooks/useTranslatedString';
import Lecture from '@/shapes/model/subject/Lecture';
import Examtime from '@/shapes/model/subject/Examtime';
import { RootState } from '@/redux';
import { Detail } from '@/shapes/state/timetable/LectureFocus';

const ExamSubSection: React.FC = () => {
const { t } = useTranslation();
const dispatch = useDispatch();
const translate = useTranslatedString();

const lectureFocus = useSelector((state: RootState) => state.timetable.lectureFocus);
const selectedTimetable = useSelector(
(state: RootState) => state.timetable.timetable.selectedTimetable,
);
const setMultipleFoucsDispatch = (multipleTitle: string, multipleDetails: Detail[]) =>
dispatch(setMultipleFocus(multipleTitle, multipleDetails));
const clearMultipleFocusDispatch = () => dispatch(clearMultipleFocus());

const [multipleFocusDayIndex, setMultipleFocusDayIndex] = useState<number | null>(null);

const _getOverallLecEtPairs = () => {
return getOverallLectures(selectedTimetable, lectureFocus)
.map((l) =>
l.examtimes.map((et) => ({
lecture: l,
examtime: et,
})),
)
.flat(1);
};

const _getLecEtPairsOnDay = (dayIndex: number) =>
_getOverallLecEtPairs().filter((p) => p.examtime.day === dayIndex);

const setFocusOnExam = (dayIndex: number) => {
if (lectureFocus.from !== LectureFocusFrom.NONE || !selectedTimetable) {
return;
}

const lecEtPairsOnDay = _getLecEtPairsOnDay(dayIndex);
const details = lecEtPairsOnDay.map((p) => ({
lecture: p.lecture,
name: translate(p.lecture, 'title'),
info: getTimeStr(p.examtime),
}));
setMultipleFoucsDispatch(t('ui.others.examOfDay', { day: getDayStr(dayIndex) }), details);
setMultipleFocusDayIndex(dayIndex);
};

const clearFocus = () => {
if (lectureFocus?.from !== LectureFocusFrom.MULTIPLE) {
return;
}

clearMultipleFocusDispatch();
setMultipleFocusDayIndex(null);
};

const mapPairToElem = (lecEtPair: { lecture: Lecture; examtime: Examtime }) => {
const isFocused =
isSingleFocused(lecEtPair.lecture, lectureFocus) ||
multipleFocusDayIndex === lecEtPair.examtime.day;
return (
<li className={classNames(isFocused ? 'focused' : null)} key={lecEtPair.lecture.id}>
<div>{translate(lecEtPair.lecture, 'title')}</div>
<div>{getTimeStr(lecEtPair.examtime)}</div>
</li>
);
};

return (
<div className={classNames('subsection--exam', 'mobile-hidden')}>
<div className={classNames('subsection--exam__title')}>
<span>{t('ui.title.exams')}</span>
</div>
<div className={classNames('subsection--exam__content')}>
<Scroller>
{[0, 1, 2, 3, 4].map((dayIndex) => (
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

day enum 있으면 가져다 써도 좋을 듯

Suggested change
{[0, 1, 2, 3, 4].map((dayIndex) => (
{Object.values(DayEnum).map((dayIndex) => (

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

요거 좋을 것 같아서 찾아봤는데
const Enum 으로 선언된 값은 실제 런타임에서 javascript 객체로 존재하지 않고 인라인으로 치환되어서, Object.values(DayEnum) 과 같이 사용할 수 없는 것 같아요.
대신에 요런 식으로는 바꿀 수 있을 것 같아요. 저는 명시적으로 어떤 enum 인지 알려주는 게 좋은 것 같은데, 어떤게 좋을지 의견 주시면 감사하겠습니다!

{[Day.MON, Day.TUE, Day.WED, Day.THU, Day.FRI].map((dayIndex) => (

참고
image

Copy link
Member

@yumincho yumincho Aug 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

enum 관련 논의가 전에 있었던 것 같은데..Day enum 포함해서 enum.ts에서 관리하던 enum들 as const로 옮기는 게 나을까요?

cf. [타입 스크립트 핸드북] Objects vs. enums

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

옹 넵.! 체킹이 아니라 런타임에서 enum 을 많이 가져다 써서 객체 - as Const 로 하는게 좋을 것 같은데, 오늘 회의시간에 논의하고 확정하면 어떨까요?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

좋슴다 👍

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#73
요기에서 수정이 되었는데,
as Const 로 바꾸니 지금Semester.Spring이런 식으로 되어 있는 것들을 모두 Semester['Spring'] 이렇게 바꾸어야 해서 default value 를 할당하는 방향으로 바꾸었습니당

<div
key={dayIndex}
className={classNames('subsection--exam__content__day')}
onMouseOver={() => setFocusOnExam(dayIndex)}
onMouseOut={() => clearFocus()}>
<div className={classNames(t('jsx.className.fixedByLang'))}>
{t(
`ui.day.${
[
'mondayShort',
'tuesdayShort',
'wednesdayShort',
'thursdayShort',
'fridayShort',
][dayIndex]
}`,
)}
</div>
<ul>{_getLecEtPairsOnDay(dayIndex).map((p) => mapPairToElem(p))}</ul>
</div>
))}
</Scroller>
</div>
</div>
);
};

export default ExamSubSection;
Loading