Life-Calendar#10 | diary 기능 (part.2)

김하은·2023년 1월 22일
2

Project

목록 보기
8/18
post-thumbnail

🎈내용 작성후 등록 버튼 누르면 선택한 color값과 내용이 등록됨.
🎈 글 입력후 등록 버튼 누르면 아래에 title 제목만 보이게 글 추가하기 .
🎈 등록된 titlebox 클릭시 입력칸에 저장된 content 가 보이고, 수정하면 수정알림이 뜸

이전까지 내용을 작성하고, recoil을 사용하여 색을 선택하면, 그 색이 다이어리 배경색에 반영되는것까지 구현하였다.

이제 , 등록 버튼을 누르면 선택한 색이 반영되서 등록된 모습을 구현하겠다.

🔥point🔥

-> 등록 되었을때 title 만 보임, 등록 될시 나타내는곳에 silde 기능 추가, 한달 단위로 만 title이보임

📁5Page
L components
L diaryFrom.js

🚩silde 기능 추가

-> slide 라이브러리가 있었다. 따라, 이 slide의 라이브러리를 써보기로 하였다.
다른 구현 방법이 있을까 찾아보았는데 , 시간 절약과 가독성을 위해 해당 라이브러리를 썼다.

다운로드 방법

npm install react-slick

기본import (기본적인 css가 있기 때문에 import css 를 해주었다.)

import "slick-carousel/slick/slick.css";
import "slick-carousel/slick/slick-theme.css";

slide 기본 setting 값

const settings = {
    dots: true,
    arrow: false,
    speed: 700,
    infinite: true,
    rows: 2,
    slidesPerRow: 2,
  }

-> dots: true // 지정한 행,열 넘어갈시 아래와 같이 dote 모양으로 다음페이지의 UI가 보인다.

-> arrow: false // 좌우 화살표 모양 표시
->speed: 700 // 슬라이드 속도
->infinite: true // 슬라이드안 보여줄 content 내용
->rows: 2 // 열. content
->slidesPerRow: 2,// 행 -> 보여질 content의 수.

적용 방법
-> npm 에 나온 사용법을 보면 Slider 를 감싸준다.
ex)

입력코드

const [list, setData] = useState([]);

const settings = {
   dots: true,
   arrow: false,
   speed: 700,
   infinite: true,
   rows: 2,
   slidesPerRow: 2,
 }
return (
   <>
       <WhiteContainer>
         <div className="sliderWrap">
           <Slider {...settings}>
           {list.map((item) => (
             <DiaryBoxContainer>
               <div className="diaryWrap">
                 <div className="dateBox" 
                   style={{color: item.color, borderColor: item.color}}
                 >
                   {item.date.substr(0,10)}
                   <FontAwesomeIcon className="XIcon" 
                   icon={faXmark}
                   }/>
				  </div>
                 <div 
                   className="titleBox"
                   style={{backgroundColor: item.color}}
                 >
                   <div>
                     {item.title}
                   </div>
                 </div>
               </div>
             </DiaryBoxContainer>
           ))}
           </Slider>
         </div>
       </WhiteContainer>
   </>
 );

📍 const [list, setData] = useState([]);
{list.map((item) => (
-> 쓰고 저장하는 content를 state의 list 에 저장하고 map을 이용해 객체로 return해주었다.
📍<div className="dateBox"
style={{color: item.color, borderColor: item.color}}>
{item.date.substr(0,10)}
-> 날짜가 보여지는 date 박스에도, 위에서 선택하고 저장한 color 값이 반영되게끔
style 을 주었다. 그리고 {date} 적어, 날짜를 보이게 하였다.
substr(0,10)} -현재 날짜를 표시하기 위해 자바스크립트의 new Date().toISOString() 메소드를 사용하여 0부터 10자리까지 표시하도록 작성하였다.

📍<div
className="titleBox"
style={{backgroundColor: item.color}}>

{item.title}
-> 위에 했던 date 박스와 마찬가지로, 선택한 color 색상을 반영하기 위해 titlebox style에 color값을 받아왔다. 아래의 {item.title} 로 내용의 title 만 보이도록 표시해 주었다.

-> v 아이콘을 등록 버튼으로 나타낼 것이기 때문에,
onClick 이벤트를 사용하였다. {submit} 이라는 함수를 지정 해주었다.


🚩 등록 기능 추가

체크 표시가 된 버튼을 누르면 다이어리가 등록 되는 기능을 구현할 차례이다.

<FontAwesomeIcon
   type='button'
   className="CheckIcon" 
   icon={faCircleCheck} 
   onClick={submit}
/>

-> 체크 아이콘 버튼이 등록 버튼이기 때문에 check icon 에 onClick 이벤트를 걸어주고
함수를 지정해 주었다.
클릭시 {submit} 이라는 함수가 실행된다.


const search = () => {
  axios.get(API_URL+ '/diary')
  .then((response) => {
  setData(response.data.data);
  })
};

const submit = () => {
  axios.post(API_URL+'/diary', {
    title:ViewData.title
   ,content:ViewData.content
   ,date:ViewData.date
   ,color:ViewData.color
  }).then((response)=>{
    alert("완료");
    search();
  })
};
/>

-> 📍 공통으로 쓰이는 api는 따로 공통 함수로 지정해 두었다. (API_URL)
📍 post 로 diary 생성을 해주고, ViewData 를 통해 현재의 데이터들을 보내주었다.
📍 등록이 되면 alert 창으로 '완료' 창을 띄어주었다.
📍 완료를 하고나선 diary가 등록된 모습을 다시 호출해야 하기 때문에 호출되는 로직을 따로
함수로 만들어 주었다.
📍 post.get 방식으로 데이터들을 호출해주었고, 위에 적어 두었던
[list, setData] setDtata 에 받아온 데이터들을 저장해 두었다.

💜결과

-> 일단 선택한 날짜와, 색상과 , 내용은 잘 등록 되서 보인다.

❌❌❌❌❌오류 ❌❌❌❌❌❌

-> 등록 해서 저장이 되면 diary 입력칸은 원래대로 돌아가야 하는데 등록이 되어도
내가 쓴 글들이 그대로 남아 있는것을 볼수가 있다.
내가 쓴 content 가 남아 있지 않는 모습을 보고 싶으면 작성하기 전
비어있는 데이터들을 불러와야 했었다.
비어 있는 데이터들을 불러오는 함수를 한개 만들어 주었다.

const defaultSetting = () => {
    setViewData({
       id:""
      ,title:""
      ,content:""
      ,date:new Date()
      ,color: ""
    })
  };

-> 등록이 되었을때 title과 content 는 처음 그대로 가져오고, 현재 날짜는 계속 나타내야 했기 때문에 new Date()로 지정해서 넣어주었다.

  const search = () => {
    axios.get(API_URL+ '/diary')
    .then((response) => {
    setData(response.data.data);
    })
  };

  const defaultSetting = () => {
    setViewData({
       id:""
      ,title:""
      ,content:""
      ,date:new Date()
      ,color: ""
    })
  };
  
  const submit = () => {
    axios.post(API_URL+'/diary', {
      title:ViewData.title
     ,content:ViewData.content
     ,date:ViewData.date
     ,color:ViewData.color
    }).then((response)=>{
      alert("완료");
      defaultSetting();
      search();
    })
  };
  
  return(
  	<FontAwesomeIcon
       type='button'
       className="CheckIcon" 
       icon={faCircleCheck} 
       onClick={submit}
	/>
  )
  };

-> 버튼 클릭시 submit 함수가 실행되고 content 등록이 된후
비어 있는 데이터들 호출되어 보여지고, 등록된후의 모습을 호출하도록 넣어주었다.

❌❌❌❌❌오류2 ❌❌❌❌❌❌

-> 등록 버튼을 누르면 등록된 모습이 잘 보이고, title과 content 입력칸도 처음으로 돌아간다. 하지만.. 뭔가 허전하다..😫.. diary 배경색은 원래대로 돌아오지 않는다....
🙏 내가 잘못했어.. 제발 돌아와줘.........

-> 처음으로 돌아가는 로직에서 되질 않으니 처음 비버있는 데이터를 불러오는
defaultSetting 함수를 다시 수정해야 할것 같다.

-> defaultSetting 에 color 맨 처음에 보이는 기본 color값을 적어두었다.

const defaultSetting = () => {
    setViewData({
       id:""
      ,title:""
      ,content:""
      ,date:new Date()
      ,color: "#5800FF"
    })
  };

💜결과

->등록후 diary 입력칸이 원래 처음대로 돌아오는 것을 볼수 있다.


🚩 추가 기능

등록시 alert 창에 선택지가 확인만 있는것을 볼수 있다.
'취소' 의 선택지를 만들어 최소버튼을 누를시 등록하기 전단계가 보이는것을 추가 구현하였다.
그리고 alert의 메세지도 '완료' -> '다이어리를 등록 하시겠습니까?'라고 수정하였다.

const submit = () => {
 axios.post(API_URL+'/diary', {
    title:ViewData.title
   ,content:ViewData.content
   ,date:ViewData.date
   ,color:ViewData.color
  }).then((response)=>{
    if(window.confirm("다이어리를 등록 하시겠습니까?")===true){
    defaultSetting();
    search()
    }else{
      alert('취소하였습니다.')
    }
  })
};

-> 확인버튼 true 시 저장된 내용을 새로 호출해 주고 그렇지 않을시 창에 취소 되었다는 알림이 뜬다.

🚩 수정 기능

목표 기능
1. 저장 된 diary title 클릭시 기존 content 창에 선택한 diary content 가 보여짐
2. content 수정후 등록 v 버튼 클릭시 alert 창으로 '수정 하시겠습니까' 취소시
'다른것을 선택해주세요' 라는 알림이 뜬다.

🎈1번 기능 구현
생각해보기
-> 등록된 titlebox 에 click이벤트. 다이어리가 보여지는 함수 한개를 만들어서
클릭시 이벤트 함수가 호출 되게 끔 한다.

const Viewdiary = (item) => {
      setViewData({
           title : item.title
          ,content : item.content
          ,color : item.color
          ,id : item._id
          ,date : new Date(item.date)
      })
  };
 return(
  	<div 
     className="titleBox"
     style={{backgroundColor: item.color}}
     onClick={() => Viewdiary(item)}
     >
  );
  

-> id값은 content에 등록된 id값을 가져와야 하기때문에 item._id 로 가져왔다.

🎈2번 기능 구현
-> 현재 내용이 수정한 내용인지 아닌지 판별하기 위한 상태값이 필요하다.

따라 임의로 버튼 상태값을 state 로 지정해주었다.

Viewdiary 함수게 조건값을 넣어

const Viewdiary = (item) => {
    if(ViewData.id !== item._id){
      setViewData({
           title : item.title
          ,content : item.content
          ,color : item.color
          ,id : item._id
          ,date : new Date(item.date)
      })
      setBtnStatus(true);
    }
  };

-> 기존 ViewData.id 와 작성된 글 item._id 값이 일치 하지 않을시
setViewData 를 통하여 작성된 내용들을 보여준후
버튼의 상태값이 true 로 된다.

const [btnStatus, setBtnStatus] = useState(false);
     
     
 const Viewdiary = (item) => {
   if(ViewData.id !== item._id){
     setViewData({
          title : item.title
         ,content : item.content
         ,color : item.color
         ,id : item._id
         ,date : new Date(item.date)
     })
     setBtnStatus(true);
   }
 };    
     
     
const submit = () => {
   if(!btnStatus){
     console.log(ViewData);
       axios.post(API_URL+'/diary', {
          title: ViewData.title
         ,content: ViewData.content
         ,date: ViewData.date
         //,date: new Date()
         ,color: colorPeeker
       }).then((response) => {
         if(window.confirm('다이어리를 등록 하시겠습니까?')===true){
         defaultSetting();
         search();
       }else{
         alert('취소 하였습니다.')
       }
     })
   }else{
       if(window.confirm('수정하시겠습니까?')){
         console.log(ViewData);
         axios.patch(API_URL+ '/diary/' + ViewData.id,{
           title:ViewData.title
           ,content: ViewData.content
           ,date: ViewData.date
           ,color: ViewData.color
         }).then((response) => {
           if(response.data.message === "successful"){
             search()
             setViewData({
                id:""
               ,title:""
               ,content:""
               ,date:new Date()
               ,color:"#5800FF"
             })
             setBtnStatus(false);
           } else {
             console.error(response.data.message)
           }
         })
       }else{
         alert("취소 되었습니다.")
       }
   }
 };
    
 return(
     <div 
      className="titleBox"
      style={{backgroundColor: item.color}}
      onClick={() => Viewdiary(item)}
     >
     );
    

->
1. 기존 ViewData.id 와 작성된 글 item._id 값이 일치 하지 않을시
setViewData 를 통하여 작성된 내용들을 보여준후
버튼의 상태값이 true 로 된다.

  1. 등록 함수 의 조건을 걸어준뒤 if(!btnStatus){
    -> true 값이 (!btnStatus) 해당 조건을 타면 false 값으로 되기 때문에 아래의 true 조건의 else 로직이 타진다. 따라 버튼 상태값 true인 아래 수정하시겠습니까의 로직이 타지면서 등록 버튼을 눌렀을시 alert창으로 수정 하시겠습니까?
    의 알림창이 뜬다.

💜결과

-> 기존의 diary에 등록된 글을 클릭하면 입력칸에 보이고 수정후, 등록 버튼을 누르면
alert 창으로 "수정하시겠습니까?" 라는 알림이 뜬다. 확인을 누르면 기존에 있던 내용이 수정된 모습으로 보인다.


다음으로 해결할 오류 "time Zone" 오류

profile
꾸준함을 이기는것은 없다

0개의 댓글