처음에는 datepicker 라이브러리를 사용할려고 했는데
멍청하게 달력을 만들어두고 또 라이브러리를 사용할려고 했다.
이번 프로젝트 목표는 라이브러리를 최대한 사용하지않고 구현하는것이다.
import { useState } from 'react';
import moment from 'moment';
import './assets/css/modal.scss'
function Modal({ setmodal }) {
const [x, setx] = useState(10000)
const [y, sety] = useState(10000)
const [endx, setendx] = useState(10000)
const [endy, setendy] = useState(10000)
const [start, setstart] = useState(moment().format('YYYYMMDD'))
const [end, setend] = useState(moment().format('YYYYMMDD'))
const close_modal = (e) => {
e.preventDefault()
if (e.target.className === 'modal') {
setmodal(false)
}
if (e.target.className != 'modal_button_start') {
setx(10000)
sety(10000)
}
if (e.target.className != 'modal_button_end') {
setendx(10000)
setendy(10000)
}
}
const show_calendar = (e) => {
if (e.target.className == 'modal_button_start') {
setx(e.clientY + 30)
sety(e.clientX - 20)
}
if (e.target.className == 'modal_button_end') {
setendx(e.clientY + 30)
setendy(e.clientX - 20)
}
}
return (
<div className='modal' onClick={(e) => close_modal(e)} value={true}>
<div >
<div className='modal_div'>
<div className='modal_title'>
일정 추가하기
</div>
<div className='modal_body'>
내용입니다.
<textarea></textarea>
<div onClick={(e) => show_calendar(e)} >
<div>시작 일정</div>
<input className='modal_button_start' value={start} readOnly></input>
</div>
<div style={{ top: x, left: y, position: 'absolute' }} className='modal_calendar'>
<Day_kor></Day_kor>
<Date_picker setstart={setstart}></Date_picker>
</div>
<div onClick={(e) => show_calendar(e)} >
<div>종료 일정</div>
<input className='modal_button_end' value={end} readOnly></input>
</div>
<div style={{ top: endx, left: endy, position: 'absolute' }} className='modal_calendar'>
<Day_kor></Day_kor>
<Date_picker setstart={setend}></Date_picker>
</div>
</div>
</div>
</div>
</div>
)
}
function Date_picker({ setstart }) {
const [getMoment, setMoment] = useState(moment());
const today = getMoment;
const firstWeek = today.clone().startOf('month').week();
const lastWeek = today.clone().endOf('month').week() === 1 ? 53 : today.clone().endOf('month').week();
let result = [];
let week = firstWeek;
for (week; week <= lastWeek; week++) {
result = result.concat(
<div className='calendar_body_line' key={week}>
{
Array(7).fill(0).map((data, index) => {
let days = today.clone().startOf('year').week(week).startOf('week').add(index, 'day'); //d로해도되지만 직관성
if (moment().format('YYYYMMDD') === days.format('YYYYMMDD')) {
return (
<div className='calendar_body_days' onClick={() => setstart(days.format('YYYYMMDD'))} key={index} >
<span style={{ color: 'red' }}>{days.format('D')}</span>
</div>
);
} else if (days.format('MM') !== today.format('MM')) {
return (
<div className='calendar_body_days' onClick={() => setstart(days.format('YYYYMMDD'))} key={index} >
<span style={{ color: 'gray' }}>{days.format('D')}</span>
</div>
);
} else {
return (
<div className='calendar_body_days' onClick={() => setstart(days.format('YYYYMMDD'))} key={index} >
<span>{days.format('D')}</span>
</div>
);
}
})
}
</div>
);
}
return result;
}
function Day_kor() {
return (
<>
<div className='calendar_body_head'>
<div style={{ color: 'red' }} className='calendar_body_head_days'>
일
</div>
<div className='calendar_body_head_days'>
월
</div>
<div className='calendar_body_head_days'>
화
</div>
<div className='calendar_body_head_days'>
수
</div>
<div className='calendar_body_head_days'>
목
</div>
<div className='calendar_body_head_days'>
금
</div>
<div className='calendar_body_head_days'>
토
</div>
</div>
</>
)
}
export default Modal;
우선 전체 코드이다.
modal.scss
.modal{
color:#00A5FF;
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
background: rgba(0, 0, 0, 0.6);
display: flex;
justify-content: center;
align-items: center;
.modal_div{
background-color: white;
height: 90vh;
width: 90vw;
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
.modal_title{
display: flex;
align-items: center;
justify-content: center;
margin: 5px;
font-size: 3vh;
height: 10%;
width: 90%;
border: 2px solid #00A5FF;
}
.modal_body{
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
height: 80%;
width: 90%;
border: 2px solid #00C3FF;
.modal_button_start{
text-align: center;
margin:10px;
padding: 2px;
}
.modal_button_end{
text-align: center;
margin:10px;
padding: 2px;
}
.modal_calendar{
display: flex;
flex-direction: column;
border: 2px solid #00C3FF;
background-color: #96FFFF;
border-radius: 5px;
padding: 5px;
font-size: 2vh;
.calendar_body_head{
color : rgb(15, 15, 15);
display: flex;
.calendar_body_head_days{
width: 100%;
font-size:2vw;
}
}
.calendar_body_line{
display:flex;
flex-direction: row;
width: 100%;
height: 100%;
.calendar_body_days{
display:flex;
flex-direction: column;
width: 100%;
height:100%;
font-size : 2vw;
margin:2px;
padding: 1px;
}
.calendar_body_days :hover{
cursor: pointer;
border-radius: 5px;
background-color: #00e1ff;
}
}
}
}
}
}
이번에 리팩토링 하면서 모달창을 새로 옮겼다.
<div onClick={(e) => show_calendar(e)} >
<div>시작 일정</div>
<input className='modal_button_start' value={start} readOnly></input>
</div>
<div style={{ top: x, left: y, position: 'absolute' }} className='modal_calendar'>
<Day_kor></Day_kor>
<Date_picker setstart={setstart}></Date_picker>
</div>
우선 input태그 를 누를경우에 일정을 나오게 했다.
const show_calendar = (e) => {
if (e.target.className == 'modal_button_start') {
setx(e.clientY + 30)
sety(e.clientX - 20)
}
if (e.target.className == 'modal_button_end') {
setendx(e.clientY + 30)
setendy(e.clientX - 20)
}
show_calendar
함수는 className 이 모달 input태그의 클래스 네임과 동일할경우에 state를 사용해서 캘린더의 top , left를 지정해서
클릭한 위치 근처에 달력이 나오도록 설정을 했다.
그리고 setstart
를 Date_picker에 props로 넘겨줘서 날짜를 클릭했을시에
값이 바뀌도록 해두었다.
코딩한것을 글로 설명할려니까 너무 어렵다..
주석을 잘 달아야 할것같다.