1. 날짜 세팅하기 : 오늘 날짜를 기준으로 해당 주의 월요일 ~ 일요일
(참고: https://askjavascript.com/how-to-get-first-and-last-day-of-the-current-week-in-javascript/)
// 오늘 날짜
const currentDate = new Date();
// 오늘 요일 일 0 ~ 토 6
const currentDay = currentDate.getDay()
// 월요일 구하기 (오늘 날짜 - 오늘 요일 + 1)
const monday = new Date(currentDate);
monday.setDate(currentDate.getDate() - currentDay + 1);
// 일요일 구하기 (오늘 날짜 - 오늘 요일 + 7)
const sunday = new Date(currentDate);
sunday.setDate(currentDate.getDate() - currentDay + 7)
// 참고에 있는 링크는 일요일을 한 주의 시작으로 보기 때문에 거기서 +1씩 해서
// 월요일을 한 주의 시작으로 세팅하였다.
화살표 버튼을 누르면 주 단위로 앞 뒤로 이동
const handleWeek = (direction) => {
// direction -1 왼쪽 / 1 오른쪽
if(direction === -1) {
// 한 주 감소
setCurrentDate(new Date(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate() - 7))
} else {
// 한 주 증가
setCurrentDate(new Date(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate() + 7))
}
}
2. 날짜별 데이터 가져오기
월요일 ms ~ 일요일 ms 사이에 writtenDate 값 필터링
// 선택된 주의 paln
const mondayMs = monday.getTime();
const sundayMs = sunday.getTime();
const thisWeekPlan = filteredWeekPlan.filter(
(it) => mondayMs <= it.writtenDate && it.writtenDate <= sundayMs
);
const thisWeekDailyPlan = filteredDayPlan.filter(
(it) => mondayMs <= it.writtenDate && it.writtenDate <= sundayMs
);
3. 해당 주의 week plan 세팅
redux store subject안에 subject별 색상이 정해져 있기 때문에 중간에 subColor를 지정하는 함수를 추가하였다.
<div className="home_week_area">
<div>This week's plan</div>
<div className="week_goals">
{thisWeekPlan.map((it) =>
it.goal.map((goal) => {
// subject 정보에서 이름이 일치하는 정보를 찾아 색상 지정
let subColor = "";
filteredSubject.map((sub) => {
if (sub.subject === goal.weekGoalSubject) {
subColor = sub.color;
}
});
return (
<span className="goal_item" key={goal.weekGoalId}>
<span>
{goal.weekGoalComplete ? (
<FontAwesomeIcon icon={faSquareCheck} />
) : (
<FontAwesomeIcon icon={faSquare} />
)}
</span>
<span
className="subject"
style={{ backgroundColor: `${subColor}` }}
>
{goal.weekGoalSubject}
</span>
<span>{goal.weekGoalContent}</span>
</span>
);
})
)}
</div>
</div>
4. 해당 주의 daily plan
처음에는 위와 같이 dayPlan 배열을 map으로 돌려서 7개의 item(日칸 하나하나)를 만들려고 하였는데,
생각해보니 저렇게 하면 만약, 데이터가 하루 없다면(ex: 화요일 데이터 없음) 6개의 칸만 만들어지게 되기 때문에 위와 같이는 하면 안되는 것이였다.
* 잘못한 처음 코드
더보기
{filteredDayPlan.map((it) => (
<div className="home_daily_item">
<div>
<span>
{/* 날짜 */}
{`${new Date(it.writtenDate).getMonth() + 1}/${new Date(
it.writtenDate
).getDate()}`}
</span>
<span>
{/* 요일 */}
{(() => {
let day = "";
switch (new Date(it.writtenDate).getDay()) {
case 0:
day = "SUN";
break;
case 1:
day = "MON";
break;
case 2:
day = "TUE";
break;
case 3:
day = "WED";
break;
case 4:
day = "THU";
break;
case 5:
day = "FRI";
break;
case 6:
day = "SAT";
break;
}
return day;
})()}
</span>
</div>
<div>
{it.goal.map((goal) => {
// subject 정보에서 이름이 일치하는 정보를 찾아 색상 지정
let subColor = "";
filteredSubject.map((sub) => {
if (sub.subject === goal.dailyGoalSubject) {
subColor = sub.color;
}
});
return (
<span className="goal_item">
<span>
{goal.dailyGoalComplete ? (
<FontAwesomeIcon icon={faSquareCheck} />
) : (
<FontAwesomeIcon icon={faSquare} />
)}
</span>
<span
className="subject"
style={{ backgroundColor: `${subColor}` }}
>
{goal.dailyGoalSubject}
</span>
<span>{goal.dailyGoalContent}</span>
</span>
);
})}
</div>
</div>
))}
그렇다면, 7개의 칸과 각각의 칸의 mon~sun은 원래 고정된 상태로 그 안에 날짜랑 계획 데이터만 집어 넣어야 하는 것이다.
// 먼저 반복할 칸의 배열을 만들어 준다.
const sevenDays = ["MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN"];
return
<div className="home_daily_area">
{sevenDays.map((days, index) => (
<div className="home_daily_item">
<div>
<span>
// 날짜 지정할 때 사용한 monday 정보를 복사하여 각각 칸에 날짜를 monday + 0 ~ 6일 더해주었다.
{(() => {
const thisMonday = new Date(monday);
let date = thisMonday.setDate(monday.getDate() + index);
return `${new Date(date).getMonth() + 1}/${new Date(
date
).getDate()}`;
})()}
</span>
<span>{days}</span>
</div>
<div>
// 위와 같이 7개의 날짜 정보를 불러와 각각 컴포넌트를 생성하고
// 해당 날짜(date), 필터링된 데이터(item), 필터링된 주제(sub)를 전달한다.
{(() => {
const thisMonday = new Date(monday);
let date = thisMonday.setDate(monday.getDate() + index);
return <GoalItem date={date} item={thisWeekDailyPlan} sub={filteredSubject}/>
})()}
</div>
</div>
))}
</div>
// GoalItem
const GoalItem = ({date, item, sub}) => {
return (
<div>
{item.map((it) =>
it.goal.map((goal) => {
// 날짜가 일치하지 확인
if (date === new Date(it.writtenDate).setHours(0, 0, 0, 0)) {
// 주제 색상 지정
let subColor = 'red';
sub.map((sub) => {
if (sub.subject === goal.dailyGoalSubject) {
subColor = sub.color;
}
});
return (
<span className={`goal_item ${date}`} key={it.id}>
<span>
{goal.dailyGoalComplete ? (
<FontAwesomeIcon icon={faSquareCheck} />
) : (
<FontAwesomeIcon icon={faSquare} />
)}
</span>
<span className="subject" style={{ backgroundColor: `${subColor}` }}>
{goal.dailyGoalSubject}
</span>
<span>{goal.dailyGoalContent}</span>
</span>
);
} else {
return null;
}
})
)}
</div>
);
}
이렇게 한다면 해당 날짜에 해당하는 데이터를 각각의 칸에 집어넣을 수 있게 된다.
'JS > React Project' 카테고리의 다른 글
🔥 firebase 배포하기 (0) | 2023.10.17 |
---|---|
📆 위클리 플래너 - 주제 (0) | 2023.09.07 |
📆 위클리 플래너 - 첫화면, 로그인 (0) | 2023.09.05 |
🏃♀️ 목표 다이어리 - 글 작성 / 수정 (0) | 2023.08.07 |
🏃♀️ 목표 다이어리 만들기 - 홈화면 (0) | 2023.08.01 |