#16 중요 로직들 - 5 (feat. 캘린더 디자인)

김대진·2023년 3월 21일
0

Sekkison Project

목록 보기
17/22
post-thumbnail

앞서서 약속을 만들고, 참가하는 페이지들을 만들어 보았고, 이제 자신이 참가한 약속들을 캘린더 형식으로 보여줄 것이다.

이를 위해서, 서버에 연도와 달, 유저id를 보내면 해당 유저가 그 달에 한 약속들을 리턴해주는 컨트롤러와 서비스를 작성하였다.

Controller

@ResponseBody
@GetMapping("/calender/{userId}/{year}/{month}")
// 해당 달의 내 약속 가져오기
public ResponseForm getCalenderAppoint(
    @PathVariable("userId") Long userId,
    @PathVariable("year") Integer year,
    @PathVariable("month") Integer month) {
    return appointService.getCalenderAppoint(userId, year, month);
}

Service

// 해당 날짜의 내 약속 가져오기
public ResponseForm getCalenderAppoint(Long userId, Integer year, Integer month) {
    List<List<Appoint>> data = new ArrayList<>();
    for(int i = 0; i < 32; i++) data.add(new ArrayList<>());

	// 내 약속 가져오기
    List<MyAppoint> mas = myAppointRepository.findByUserId(userId);
    for(MyAppoint ma : mas) {
    	Appoint a = appointRepository.findById(ma.getAppointId()).orElse(null);
    	LocalDateTime t = a.getDday();

		// 해당 날짜가 아니면 패스
		if (t.getYear() != year) continue;
    	if (t.getMonthValue() != month) continue;
    	data.get(t.getDayOfMonth()).add(a);
	}
	return new ResponseForm().setSuccess(data);
}

이제 프론트에서 ajax로 데이터를 요청하면 해당 달의 약속들이 리스트에 저장되어 만약 그 달 15일의 데이터를 사용하고 싶다면 response[15] 로 받을 수 있다. 다음은 그 데이터를 받는 자바스크립트 코드이다.

javascript

let today = new Date();
let year = today.getFullYear();
let month = today.getMonth() + 1;
let calenderData;
const todayArr = [year, month, today.getDate()];
const days = ["일", "월", "화", "수", "목", "금", "토"];
for(let i = 0; i < 7; i++) $("#trHead").append(
  `<td>
	  <div class="head" style="display : flex; justify-content : center; align-items : center;">
	     ${days[i]}
	  </div>
   </td>`);

getAppoints(year, month);
function getAppoints(y, m) {
  $.ajax({ 
    url:`${path}/appoints/calender/${userId}/${y}/${m}`,
    type:"GET",
    cache:false,
    success : function(data) {
      if (data.success) {
        calenderData = data.data;
        setAppoints(data.data, y, m);
      }
      else console.log(data.msg);
    }
  });
}

다음은 받은 정보들을 캘린더에 표시하기 위한 css와 html이다.

css

table { width: 100%; }
.ttd {
   width: 14.28%;
   position: relative;
}
.ttd:after {
   content: '';
   display: block;
   margin-top: 100%;
}
.head {
   padding:0.2rem;
   color:white;
   font-weight:bold;
   background-color: orange;
}
.ttd .cell {
   cursor:pointer;
   overflow:hidden;
   font-size:0.7rem;
   position: absolute;
   top: 0;
   bottom: 0;
   left: 0;
   right: 0;
   background: bisque;
}
.ttd .cell:hover {
   outline:2px solid lightsalmon;
}
.today {
   border:2px solid darkgoldenrod;
}
.sm { font-size:0.2rem; margin:0.05rem; padding:0.05rem;}
.co0 { background-color: darkred; color:white; }
.co1 { background-color: darkslateblue; color:white; }
.co2 { background-color: darkgreen; color:white; }
.co3 {background-color:darkviolet; color:white;}

html

<table>
  <tr id="trHead"></tr>
  <tr id="tr0"></tr>
  <tr id="tr1"></tr>
  <tr id="tr2"></tr>
  <tr id="tr3"></tr>
  <tr id="tr4"></tr>
  <tr id="tr5"></tr>
  <tr id="tr6"></tr>
</table>
<div id="appointList"></div>

이제 만들어 놓은 html에 데이터를 담기만 하면 끝이다. 아래는 캘린더를 구성하는 자바스크립트 코드이다.

javascript

// 달력 세팅
function setAppoints(data, y, m) {
   $("#YM").html(`${y}${m}`)
   let start = new Date(y, m-1, 1).getDay();
   let monthDays = new Date(y, m, 0).getDate();

   const out = [];
   let date = 0;
   for(let i = 0; i <= 42; i++) {
      if (i % 7 == 0) { $(`#tr${i/7}`).html(out); out.length = 0; }

      if (date >= monthDays || i < start) out.push(`<td></td>`);
      else {
         date++;
         let apps = data[date];
         let text = '';
         text += 
           `<td class="ttd">
               <div class="${y == todayArr[0] && m == todayArr[1] && date == todayArr[2] ? "today" : ""} cell"token interpolation">${y}, ${m}, ${date})">
                  <div class="sm">${date}</div>`;
         if (apps.length != 0) {
            for(let a = 0; a < apps.length; a++) {
            text += 
               `<div class="sm co${a}" style="white-space: nowrap;">
                  ${apps[a].title}
               </div>`;
         }
      }
      text += `</div></tr>`;
      out.push(text);
      }
   }
}

캘린더 안의 날짜 박스를 스크린의 크기가 변해도 항상 정사각형으로 만드는 것이 조금 어려웠던 작업이었다. 탬플릿을 쓸 수도 있었지만, 불필요한 코드가 많고 우리 프로젝트에 맞춰서 코드를 수정하기 어려울 것이라 판단해 직접 만들게 되었다.

그래서, 나와 같은 사람들을 위해 이번 게시글은 프론트 코드를 거의 붙여넣다싶이 해서 작성하였다. 따라만 한다면 데이터를 표시해주는 캘린더를 만들 수 있을 것이다.

profile
만재 개발자

0개의 댓글