오픈소스로 나와있는 calendar api 들이 많지만,
필자의 경우 커스텀할 일이 많아 직접 캘린더를 구현해볼 것이다.
1.전제조건
1) 종료일자기준 30일전부터 캘린더에 전부 표현할 것 , 1개의 캘린더에 모든 날짜가 들어간다.
2) 설명을 위한 글이므로 소스코드를 여러페이지에 분리하지 않고 한 페이지에 구현
3) state, dispatch 등 calendar 설명에 불 필요한 부분은 과감히 생략
4) 꼭 필요한 부분은 소스코드에 명시할 것이며 css 관련해서는 자세하게 작성하지 않는다.
5) 순수하게 캘린더에 필요한 부분만 작성할 것이며 상황에 따른 커스텀은 따로 하길 바란다.
6) 설명을 위해 일부 주석이 들어갈 수 있다.
2. 소스코드(JS)
import React, {useState } from 'react';
import moment from 'moment';
const [dayArray, setDayArray] = useState<any>({ array: [] }); // 실제 캘린더 데이터
const dayInit: any = {
monthIndex: 0,
weekIndex: 0,
weekData: "",
day: "--",
status: {
영업구분 : { check : true, 근로자수 : 0} ,
},
func: {
onClick: false,
}
}
var calcEndDate = moment(data.basicInfoState.customer_calc_basic_date);
var calcStartDate = moment(data.basicInfoState.customer_calc_basic_date).subtract(30,'d');
var tempCalcStartDate = moment(data.basicInfoState.customer_calc_basic_date).subtract(30,'d');
const dayArrayInit = () => { // 캘린더 작성 버튼 클릭 이후
let monthIndex = 0; // 일자별 구분
let totalResult: any[] = []; // 전체 배열
let calc_day : any = calcStartDate; // 시작일자 기준값
if(calc_day.day() === 0){ // 종료일자 기준 30일 전이 일요일이면 아무행위를 하지않음
}else { // 종료일자 기준 30일 전이 일요일이 아닐 경우 해당 날짜만큼 차감하여 일요일로 만든다.
calc_day.subtract(calc_day.day(),'days');
}
for(let j= calc_day.week(); j <= calcEndDate.week(); j++){ // 첫주차~마지막주차까지 반복
let weekArray : any[] = []; // 일주일 단위 데이터
for(let z = 0; z < 7; z++){ // 주차별 일요일~토요일까지 반복한다.
var dayData: any = {
monthIndex: 0,
weekIndex: 0,
weekData: "",
day: "--",
status: {
영업구분 : {check : true, 근로자수 : 0},
},
func: { onClick: true }
}
let dayType : any = moment(calc_day.format('YYYY-MM-DD').day()); // 무슨 요일인지 선언함
if(calc_day.isAfter(calcEndDate) === false && calc_day.isAfter(tempCalcStartDate) === true){
// 시작일자부터 종료일자에 속하면, 정확한 데이터를 넣음
weekArray.push({
...dayData,
monthIndex: monthIndex,
weekIndex: z,
weekData: moment(calc_day.format('YYYY-MM-DD').day()),
day: calc_day.format('YYYY-MM-DD');
func: { onClick: true }
});
}else{
// 날짜 범위밖에서는 날짜를 입력하지 않고, 클릭할 수 있는 기능을 없앰
weekArray.push({
...dayInit,
monthIndex: 0,
weekIndex: z,
weekData: moment(calc_day.format('YYYY-MM-DD')).day(),
}) ;
}
calc_day.add(1,'days'); // 데이터를 넣었으니 기준일자를 하루씩 증가시킨다.
monthIndex++; // monthIndex 값을 1씩 증가
}
var jsonData = {
'weekData' : weekArray,
};
totalResult.push(jsonData); // 실제 데이터를 넣는다.
}
data.setDayArray({ array: totalResult }); // 실제 캘린더 데이터 배열
}
이것으로 1차적으로 캘린더를 생성하는 작업은 끝났다.
이제 이 배열을 가공하여 HTML, CSS 작업을 하면 되겠다.
** 원래 시작일자와 종료일자를 나눠, 월 단위로 캘린더를 그려지는 것을
설명하려 했는 데, 소스코드가 너무 복잡하여 이해시킬 자신이 없어
최대한 간단하게 캘린더를 구현했던 버전으로 작성한다.
월별로 캘린더를 나누고 싶은 분은 현재 소스에서 커스텀을 일부 진행하길 바란다.
위 캘린더는 moment.js를 다수 활용했으니, 메서드에 대해서 모르시는 분은 아래 글들을 참고하자.
2025.02.10 - [JS] - JS 날짜 라이브러리중 Moment.js에 대해 알아보자
'Next.js' 카테고리의 다른 글
[Next.js] Next.js 최적화 (CSS) (0) | 2025.02.12 |
---|---|
[Next.js] 버튼을 클릭하여 특정위치로 이동하자 (0) | 2025.02.12 |
[Next.js] props를 바로 넘기는방법에 대해 알아보자(Feat.useContext) (0) | 2025.02.12 |
[Next.js] Next 에서 외부 이미지를 써보자 (0) | 2025.02.12 |
[Next.js] node_modules없이 script를 로드해보자. (0) | 2025.02.12 |