회사에서 캘린더 안에 원하는 스케쥴을 추가하고 싶은 상황이 생겼다.
npm 날짜 관련 모듈이 생각보다 많다. react-day-picker, react-datepicker, react-fullcalendar 등..
날짜 자체만 선택하는 경우에는 쓸 수 있는 모듈은 엄청나게 많지만
내가 원하는 날짜를 선택하고 그 날짜에 스케줄을 추가하는 모듈을 fullcalendar 보다 좋은 모듈을 못 봤다.
이미 있는 것을 쓰는것은 참 편하지만 고객이 필요로 하는 정보를 기반으로 커스터마이징을 할 땐 결국 모듈의 힘을 빌리면 한계가 있다. 나중에 복잡해지면 오히려 편하자고 쓴 것 때문에 더 스트레스 받게된다..
그래서 그냥 만들자 해서 진짜 만들게 되었다.
먼저 Next 앱을 설치한다.
$ npx create-next-app --typescript calendar
캘린더를 만드는데 필요한 모듈을 설치한다.
$ npm i moment --save
일반적으로 우리가 생각하는 캘린더의 기본은 맨 위에 현재 연도와 월이 표시되어 있고,
이번 달이 아닌 날짜는 회색계열로 표시, 오늘 날짜는 유니크하게 표시하게 되어있다.
날짜 한 개마다 원하는 속성을 넣어주어 쉽게 커스터마이징 할 수 있는 캘린더를 만들어보자.
일단 index.tsx 파일을 깨끗하게 비우고 필요한 상태들을 선언해준다.
index.tsx
import moment from 'moment'
import type { NextPage } from 'next'
import { useEffect, useState } from 'react'
import styles from '../styles/Home.module.css'
const Home: NextPage = () => {
const [getMoment, setMoment] = useState(moment()); // 오늘
const today = getMoment; // 오늘
const todayFirstWeek = today.clone().startOf('month').week(); // 이번달의 첫째 주
const todayLastWeek = today.clone().endOf('month').week() === 1 ? 53 : today.clone().endOf('month').week(); // 이번달의 마지막 주
const [dayArray, setDayArray] = useState<any>([]); // 날짜들이 가지는 상태값들 모아둔 배열
return (
<div className={styles.container}>
</div>
)
}
export default Home
moment()를 useState에 넣고 today에 할당시켜 오늘 날짜를 가지게 하고
이번달의 첫째 주, 마지막 주의 데이터를 moment를 이용해 가져온다.
또한 날짜들의 데이터가 담길 배열을 선언해준다.
그 다음 useEffect()를 추가하여 배열 안에 이번 달의 날짜 내용을 담아준다.
useEffect(() => {
// 고유 인덱스 번호
let Index = 0;
// 이번 달 배열에 담기
let week = todayFirstWeek;
let result = []; // 이번 달 배열
for (week; week <= todayLastWeek; week++) {
let weekArray: any[] = []; // 주 별로 배열에 담음
for (var i = 0; i < 7; i++) { // 7번 반복(일주일)
let days = today.clone().startOf('year').week(week).startOf('week').add(i, 'day'); // 그날의 시간 정보
if (moment().format('YYYYMMDD') === days.format('YYYYMMDD')) { // 현재날짜일 경우
weekArray.push({
Index: i,
day: days.format('YYYY-MM-DD'),
work: "",
tardy: "",
css: {
color: "",
bgColor: "lightpink",
display: "",
},
func: {
onClick: true,
}
});
}
else if (days.format('MM') !== today.format('MM')) { // 현재 월이 아닐 경우 (클릭옵션 주지 않기 or dispaly none)
weekArray.push({
Index: i,
day: days.format('YYYY-MM-DD'),
work: "",
tardy: "",
css: {
color: "",
bgColor: "white",
display: "",
},
func: {
onClick: true,
}
});
}
else {
weekArray.push({
Index: i,
day: days.format('YYYY-MM-DD'),
work: "",
tardy: "",
css: {
color: "",
bgColor: "lightgrey",
display: "",
},
func: {
onClick: true,
}
});
}
Index++; // monthIndex 값을 1씩 증가
}
result.push(weekArray);
}
setDayArray(result);
}, []);
주석에 표기한 바와 같이 현재 날짜와 이번 달 날짜가 아닌 날짜들은 좀 다른 데이터를 넣어주었다.
이 상태로 서버를 실행하고 브라우저 콘솔로 배열을 확인해보자
날짜들에 대한 데이터가 잘 담긴 것을 확인할 수 있다.
사실상 스케줄러를 제외한 캘린더 구현은 이 데이터들을 매핑해주는 것으로 끝이다.
'Front-End > Next.js' 카테고리의 다른 글
Next.js | Redux-toolkit in Next.js( typescript ) | createAsyncThunk 비동기 API 관리 (0) | 2022.02.22 |
---|---|
Next.js | Redux-toolkit in Next.js( typescript ) | 기본 세팅 (0) | 2022.02.22 |
Next.js | Json in Json 상태 관리 (0) | 2022.01.04 |
Next.js | 기본기능 | userAgent 정보 확인하기 (0) | 2021.11.03 |
Next.js | 기본기능 | Built-In CSS Support(SCSS) (0) | 2021.11.02 |