...
▫ src>components>Modal>CreateNoteModal>CreateNoteModal.jsx






⬇
➕ : 태그를 추가하는 , ➖ : 태그 추가한 걸 빼는 것
근데 현재는 ✖누르면 삭제되어버림💥
Edit도 이렇게 되어있음
👉 태그 모달이 'add'를 위한건지 'edit'을 위한 건지에 따라 다르기에 조건처리해주기

만약, type이 'edit'을 위한 거면 이렇게 할거고 'add'를 위한 거라면 이렇게 할거임


👉 할당 된 태그는 ➖, 할당 안 된 태그는 ➕
할당 되어있는지 안 되어있는지에 따라서 조건처리해줘야함
▫ src>components>Modal>CreateNoteModal>CreateNoteModal.jsx
CreateNoteModal이 노트 생성하는 모달 컴포넌트❗
여기 데이터들이 이 코드에 다 있는데 어떠한 데이터가 이 태그들을 위한 데이터일까❓
🔖addedTag가 태그들을 위한 데이터임 ( 이걸 기준으로 조건처리 해주면 됨🔥 )
addedTag는 CreateNoteModal에 있는 데이터니까
eddedTag 이용해서 여기서 조건처리해주면 되는 것👌

DeleteBox 넣어준 담에 addedTag( 배열 )가 있을 때
find 메소드 써서 tagItem.tag( 하나의 태그 이름 ),
tag.toLowerCase( 비교할 때 대문자일 수도 있어서 소문자로 바꾸기 )
🔎find 같은게 있으면 여기 : 없으면 여기로✔
➖같은 게 있다면 이미 CreateNoteModal에 태그들이 할당되어 있다는 것
⬇
exercise 할당된 태그는 보이는데
exercise ➖는 없음
문제는 noteData.js 파일에 있는 더미데이터에서 tag 이름을 'exercise' 라고 했는데
여기에 "exercise"가 오면 문제 없었지만
없는 태그 이름을 notesData에 넣어서 문제 발생했던것🙆♀️


아예 더미데이터 없이 이렇게 [ ] 하는 게 안전제일👷♀️
그럼 이제 지금은 태그가 아무것도 없는 상태임
이 3개의 태그만 더미로 남기고
➕ 눌렀을 때 Learning이 어디로 들어가야할까❓
addedTag 여기다 넣으면 됨❗

▫ src>components>Modal>CreatNoteModal>CreateNoteModal.jsx




➖FaMinus : 얘를 클릭했을 땐 태그의 이름( tag )를 빼줘야함
▫ src>components>Modal>CreateNoteModal>CreateNoteModal.jsx
tag( 태그의 이름 ), type( "remove"인지 "add"인지 )

type에 따라 다른 로직을 해줘야함🤗

setAddedTag 여기선 addedTag 원래 있던
[ ] 여기에 이미 태그가 추가되어 있을 수도 있으니까
그래서 원래 있던 걸 prev => 가져오고 이걸 이용해서
새로운 배열 [ ]을 만들거임 ( 그래야 불변성 지켜줄 수 있음 )
새로운 배열인데 원래있던 객체 데이터 갖고 있으려면 어떻게 만들면 될까❓
👉 [ ...prev ] 🔥
여기다가 하나를 ➕추가 한거니까
{ tag: tag( 태그의 이름 ).toLowerCase( 넣어줄 때 소문자로 ), id: v4( ) }

"remove"는 ➖눌렀을 때 해당 태그를 addedTag 에서 빼주는 것👌
그럼 똑같이 state를 바꾸는거니까 setAddedTag 넣어줘야함😉
addedTag에 filter 이용해서 객체 안에 있는 { 태그의 이름 } 가져와서
태그의 이름( tag )이랑 newTag( ➖눌른 태그의 소문자 이름 ) 하고 같은 것만 빼주기😎
✍ filter : 새로운 배열을 만들어주는 메소드이기에 불변성 지켜준거임 🔥
⬇
➕누른 태그들이 잘 추가 되는 걸 볼 수 있음


➖누른 Learning 이랑 Work 제외하고
Quotes 태그만 들어온 것도 잘 되는 걸 볼 수 있음( 소문자로 잘 보임 )👀
🔖태그 ✖ 클릭하면 해당 태그 삭제되게 하기👻

CreateNoteModal.jsx 파일에서 이부분임✔
🤷♀️ 태그 오른쪽 ✖ 누르면 어떻게 해야할까 ❓
여기서 밑줄 친 부분을 통과하게 하면 됨❗ ( 지우기만 하면 되기 때문 )

⬇
✖ 누르면 해당 태그 사라지는 걸 볼 수 있음👀
🎈CreateNoteModal 에디터 만들기
에디터 만들어줄건데 스스로 만들어주긴 어렵🥴 라이브러리 이용할 것📚

이부분을 위해 이미 설치해뒀음➡react-quill 🔥
사용하는 방법은 이런식으로 어떻게 사용하는지 나와있음🧐
▫ src>components>TextEditor>TextEditor.jsx
여기서 소스 코드 작성하고
▫ src>components>Modal>CreateNoteModal>CreateNoteModal.jsx

여기로 TextEditor 컴포넌트 가져오기🤓
TextEditor 에서 필요한 데이터가 몇 개 있음🙂
에디터에 글을 어디에서 가지고 있을 거라고 했을까❓
이 content 부분에서 갖고 있음❗ ( TextEditor에 value가 필요함 )
그리고 타이핑할 때 value가 업데이트 돼야하니까 setValue도 필요⭕

TextEditor 에다가 value랑 setValue 내려주기⭐

또 하나 더 넣어줘야하는게 배경색 바꿀때마다 에디터가 색이 바뀜 ( 서로 공유🔗 )

🌈색상의 데이터는 noteColor 이부분임 ( 이것도 TextEditor 에서 필요 )
noteColor도 내려주기⭐
▫ src>components>TextEditor>TextEditor.jsx

TextEditor 컴포넌트로 와서 3개를 내려줬으니 value, setValue, color를 받아오기⚡
이렇게 되어있는데 이부분은 다 quill 라이브러리에서 제공해주는 부분

어떻게 만드냐면 ReactQuill 이렇게만 해주면 끝남..😲❗❓
근데 여기에 어떠한 설정들이 있을 것
얘네들을 어떠한 순서로 나열이 되는지 이런걸 설정을 해줄 수 있어야함
그런것들은 여기다 props로 넣어주면 됨😎








첨에 order / bullet 리스트 두 개 넣어줬음

그리고 한 칸 뛸 거니까 [ ] 이렇게 해줌

그 담은 굵게( 추가함 ), 이탤릭체, 밑줄, 취소선이니까
이렇게 해주고 한 칸 또 뛸거니까 [ ]

글자 색이랑 텍스트 안의 배경 색상,
텍스트 컬러는 여러 개 할 수 있어서 배열[ ]로 한 것 그리고 한칸 또 뛰고

이미지랑 Quot, 코드 블록
이렇게만 해주면 됨👍
⬇
실행하면 이런식으로 나옴😑
아직 CSS 파일을 import 하지 않아서 이러는 것,,

node_modules 폴더 안에 react-quill 안에 dist에 테마가 있음
⛄지금은 snow 라는 테마를 이용할거임
⬇
그러면 이런식으로 잘 보이는 걸 볼 수 있음👀
📏content 높이 지정하기
이렇게 하면 높이가 커지긴 한데 첨에 들어왔을 때부터 높이 좀 있게 하고 싶은 것
Container 만들고
🐍div 대신 Container로 감싸버림
그러면 얘가 이렇게 들어간 걸 볼 수 있음
🎰className 랜덤으로 나오는건 스타일드 컴포넌트가 랜덤으로 생성하기 때문❗
현재는 ql-editor 이부분을 200으로 높이 지정해주고 싶으면
이렇게 해주면 됨✔
⬇
쨘✨
🌈content 배경색 적용시키기

이부분 ql-editor 부분이었음
noteColor 라는 이름으로 color 내려주고

여기서 noteColor 받아오고 noteColor 해주면 됨
⬇
배경색 잘 바뀌는 걸 볼 수 있음👀
🐱💻CreateNoteModal 타이틀 나오게 해주기
아무 텍스트도 안 나오고 있음
▫ src>components>Modal>CreateNoteModal>CreateNoteModal.jsx


타입은 텍스트, value는 noteTitle, 그리고 타이핑 값을 변경해주려면
onChange 이용해서 e( 이벤트 객체 ) setNoteTitle 해서 e.target.value 해주면 됨
⬇
그럼 여기도 잘 나오는 걸 볼 수 있음👀
📑노트 저장하기 누르면 잘 적용되게 하기

이부분임


이거에 필요한 함수 handleCreateNote 만들기
여기에 이런식으로 해서 저장하기 누르면 될까...❓ 이부분을 위해 유효성 검사 해주기🧐


🚨noteTitle이 없으면 제목을 넣어주세요. 라는 문구 toast 띄워주게 할 것

content 에서 텍스트 다 지웠는데 p 태그랑 br p 태그가 남아있음🤨
다 지웠다고 해서 그냥 string 아님, 에디터에서 다 지운 기본 값이 p br p 인 것👌


🗒하나의 노트 === 🧩하나의 객체
하나의 객체 데이터를 만들어주면 됨 🆗
타이핑 한 것들을 다 모아서 태그들하고
배경색, 우선순위의 데이터도 객체에 다 들어가야함⭕
🧩우선 let note 해서 객체를 만들어줌
콘솔에 해보면 이런식으로 나옴

기본 데이터 만들어주고 여기서 조건처리해서 좀 더 필요한 데이터 넣어줄거임❗
왜냐면, 노트의 데이터는 훨씬 많음

여기서 조건처리로 나눌거임
editNote면 note의 데이터는 어떻게 될거고,
아니면 note의 데이터는 어떻게 될거야 라고 할 것🤓
✍editNote➡이미 있는 노트를 수정하려고 하면 원래 있는 노트의 데이터
✅editNote가 있다는건 수정 한다는 거고, 없다면 처음 노트를 만든다는거임

처음 노트를 만들땐 이거 이외에 더 필요한 데이터들이 있음⭕

📌isPinned 같은 경우엔 처음 만든 데이터는 핀이 되어있을 필요❌
📖isRead 같은 경우에도 읽고 있지 않은 상태니까 false로 해줌
⏰editedTime : null ( 왜냐, 첨만드는데 아직 수정한 게 아니기 때문 )
#️⃣id도 아직 없을거니까 v4( )로 넣어주면 됨
⌚createTime : 지금 생성한거니까 현재 시간을 넣어주면 됨
📅date
createTime 이랑 date 하고 같은 시간인데
실제 화면에 보여줄 때 322525323 이런식으로 보여주면 안되니까
이걸 포맷으로 올바르게 알아보기 쉽게 해주는 것🧸

📚dayjs 라이브러리 이용할 것, dayjs( 여기에 아무것도 안 넣어줬으니까 현재 시간 )
👉 일/월/년도 시간:분 오전/오후 이렇게 포맷 해주겠다는거임🔥
근데
얘네도
🤔 이렇게 와줘야함, 그럼 어떻게 해야할까 ❓
...note 해주면 됨❗
👉 새로 생성하는 노트에 대한 데이터를 만든 것
editNote : 노트에 있는 Edit 버튼 눌러서 나오는 모달창 부분

원래 있던 데이터들 뒤에 새로운 데이터를 넣는거임
editNote 에다가 수정하려고 하는 데이터에 객체를 넣어줬으나까
얘를 null로 해줘야함🌀
또 해줘야하는건 viewCreateNoteModal을 false로 해줘야함
toggleCreateNoteModal을 false로 해주면 됨⚡
🆕 그리고 새로운 데이터를 어디에 넣어줘야할까 ❓
🙆♀️ mainNotes 에다가 새로 생성한 얘를 넣어주면 됨 ❗
▫ src>store>notesList>notesListSlice.js

notesListSlice 에서 이부분을 위한걸 만들어주겠음
이름을 setMainNotes로 해주고 그런 담에 state, { payload } 가져올거임

여기에서 생성하기 버튼 눌렀을 때랑
여기서 저장하기 버튼을 눌렀을 때를 다르게 해줘야함😵

해당 노트를 수정하는 로직이랑 노트를 새롭게 생성하는 로직을 짜줘야함🐱💻
state.mainNotes 에서 현재 만들려고 하는 데이터의 id랑 mainNote에 있는
노트들 중에 id랑 같은 경우엔 해당 노트를 수정하는 로직을 해주면 되고
그렇지 않을 땐 노트를 새롭게 생성하는 로직이 되는거임✔
노트를 새롭게 생성하는 로직은 mainNotes에 노트하나를 추가하는 거니까 쉬움

노트를 수정하는 부분은 mainNotes에
여러 개의 노트 중 수정하는 애 하나만 바꿔주면 되는 것
state.mainNotes.map 이용해서 note 하나 가져오고
note 하나의 id랑 현재 바꾸려고 하는 payload id가 같으면
그땐 payload로 새롭게 바뀐 노트의 객체를 내려주고
아니면 note 객체 데이터를 넣어주면 됨 ...🥴

setMainNotes를 외부에서도 사용할 수 있게 export로 내보내기🥏
▫ src>components>Modal>CreateNoteModal>CreateNoteModal.jsx
CreateNoteModal로 와서 dispatch( setMainNotes( note ) ) 해주면 됨
⬇
노트 수정하고 저장하기 버튼 누르면
잘 저장된 걸 볼 수 있는데
문제는 content 부분에 저런식으로 나옴😑
🔖노트 수정 후 content 부분 html 태그 안 보이게 하기👻

이런식으로 나오는 걸 볼 수 있음🤔
요렇게 저장을 하고 있음
html-react-parser 이미 설치해놨었음
👉 저것들을 분석해서 브라우저에서 보여줄 수 있게 해주는 라이브러리📚
하나의 노트에서 그러는거니까 NoteCard로 이동하기🌫🐱🏍
▫ src>components>NoteCard>NoteCard.jsx


content가 이부분임
dangerouslySetInnerHTML ( InnerHTML을 위험해도 사용하겠다라는 것 )
사용해도 되지만 이거 말고 설치한 html-react-parser를 쓸거임⭕

그냥 이렇게만 해주면 됨😎
👉 HTML 문자열을 리액트 요소로 변환 해주는 역할✌
이제는 이렇게 하고 저장하기 눌러도
잘 나오는 걸 볼 수 있음👀

이렇게 나와도 상관없지만
여기에 이미지만 보이게 하고 싶다면 어떻게 하면될까❓
이부분을 조건처리해주면 됨

이 content 안에 이미지가 있는지 없는지 어떻게 알 수 있을까❓
👉 img 태그가 사용되고 있는지 알면 됨 ❗

func 라는 함수를 하나 만들기
content( string 안에 img가 )에서 포함하고 있는지 알수 있는 includes 사용하기🔥

img가 포함이 된다면 이미지가 있다는거니까
어떻게 보여줄건지 하면 되는데 이땐 그냥 content를 보여주면 되고
이미지가 없을 땐 content의 길이가 75 초과면 75자까지 보여주고 ...,
그렇지 않으면 content를 보여주겠다는 것 🆗
만든 함수 넣어주면 됨
🔬노트 클릭하면 상세하게 볼 수 있는 모달창 만들기

이미 notesListSlice.js 에서 readNote 만들어놨었음
🐱💻로직 훑어보자🔍
readNote : payload에 type이랑 id, type은 'archive', 'trash', 'main'
왜 나눴었지❓➡Main 에서도 Archive 에서도 Trash 에서도
노트 상세페이지 보여줄 수 있기 때문 ❗
mainNote에 있는 객체 데이터에서 isRead를 true로 해줄건지
아니면 archiveNotes에 있는 객체 데이터에서 isRead를 true로 해줄건지
trashNotes에 있는 객체 데이터에서 isRead를 true로 해줄건지
최대한 어디서 하는건지 알아야 좀 더 간단한 로직을 사용할 수 있을 것💡

읽으려고 하는 노트가 archiveNotes에 있다고 하면 여기 로직이 이렇게 되고
이 안에서 map 메소드로 해당 노트를 잡아서 isRead를 true로 해주는거임😯
state.archiveNotes로 하면 다이나믹하게 할 수 없으므로
state[ note ]로 해야 다이나믹 하게 할 수 있는 것🐱👓
src>store>notesList>noteListSlice.js에서
readNote export로 내보내기 안 해줬어서 내보내주기🥏
그리고 노트를 눌러야 나오는 모달창이니까 NoteCard 컴포넌트로 이동하기🌫🐱🏍
▫ src>components>NoteCard>NoteCard.jsx

ContentBox 눌렀을 때니까 onClick🖱 dispatch 하고
이름이 notesListSlice에 있는 readNote니까 dispatch( readNote ) 해주기

{ } 여기 안에 type이랑 id 넣어줘야함
근데 현재 NoteCard 안에 type, id가 이미 있음✔
type이면 type, id면 id 이렇게 해주면 됨⭕
⬇
🖱노트를 클릭하면 notesList/readNote가 호출되었고📢
읽히고 있는지 isRead가 ture로 바뀐걸 볼 수 있음👀
이제 이렇게 나오게 해줘야함


<>리액트 프래그먼트</>로 감싸주기🐍

isRead: true( note 객체 데이터 ) 이 데이터 어디에 있지❓
🧩note 객체 데이터에 isRead 여기에 있음❗

isRead가 true일 땐 ReadNoteModal 컴포넌트를 렌더링해줄것🔥

근데 여기서 보여줄 모달에 데이터가 필요( 위의 데이터 )🙆♀️
type( "notes", "archive", "trash" 모달창 어디서 열었는지 알 수 있게 )도 내려줄거임
⬇
이미 클릭했었으니까 isRead가 ture로 변경되었고
ReadNoteModal이 위에 나타난 걸 볼 수 있음👀
🤷♀️ 지정한 색으로 노트 색깔 적용되려면 어떻게 할까 ❓
✅ 저걸 이렇게 보이게 해줘야함

근데 이제 Edit 으로 배경색을 Blue로 지정했을 때
✅ 노트 색상이 이렇게 Blue로 나와야함


Card에 style={{ backgroundColor: color( note 데이터에 color로 해주면 됨 ) }}
⬇
Edit으로 배경색 변경하면 잘 적용되는 걸 볼 수 있음👀
📖ReadNoteModal UI 만들기💻

다시 노트 클릭했을 때 나오는 ReadNoteModal UI를 먼저 만들어보자❗
▫ src>components>Modal>ReadNoteModal>ReadNoteModal.jsx
첨에 어떻게 해야하지❓
모달은 다 똑같은 Modal.styled.js 파일을 사용하고 있음

이렇게 나오는 걸 볼 수 있음👀


Box는 여기 전체 감싸주는 부분

✖는 Modal.styles.js 에 있는 DeleteBox 사용할 것


FaTimes는 ✖ 아이콘
DeleteBox에 className 이렇게 넣어줄거임
✖클릭하면 모달창 닫아줘야하니까





onClick 하고 dispatch 이용해서 readNote 넣어주고,
notesListSlice 보면 type, id가 필요👌

NoteCard.jsx 에서 note( 이 안에 id가 있음 )랑 type
둘 다 내려준거 ReadNoteModal.jsx로 가져옴😎
🧩객체 안에 type은 type, id는 note 안에 id로 해주면 됨✔
이런식으로 보여주려면 먼저 title이 있어야함

div 태그 안에 객체니까 { } 해주고 note 안에 title이 있으니까 note.title 해주면 됨
그리고 여긴 content 부분


그냥 { note.content } 보여주면 안 됨❌
왜냐 p, br 태그 이런 것들이 보이기 때문에
여기도 똑같이 설치한 라이브러리 parse로 감싸주면 됨🤓
이렇게 나옴
👩🎨Read 모달창 스타일링을 해주자❗


🔸max-height➡content 많아지면 엄청 길어지기 땜에 지정해주는 것


🔸overflow-y➡여기 바깥엔 hidden으로 해줬는데
여긴 auto로 줘서 커지면 스크롤 할 수 있게끔 해줘야함
🔸justify-content: flex-end➡✖를 오른쪽 끝으로 이동시켜야하니까 end로 해주기
⬇
Note 2 title은 현재 레드 배경색인데 여긴 적용이 안 됐음

Box가 흰색 부분이니까 Box 컴포넌트 안에
style={{ backgroundColor: note.color }} 해주면 됨
note 객체 안에 color도 있어서 note.color로 해준거임 🆗
이렇게만 해주면 색깔이 잘 변경되는 걸 볼 수 있음✌
⚡정렬 버튼 누르면 정렬 모달창 나오게 하기

위에처럼 정렬 버튼 눌렀을 때 모달이 나오게 해줘야함
All Notes 부분이니까 AllNotes.jsx로 이동하기🌫🐱🏍
▫ src>pages>AllNotes>AllNotes.jsx



현재 정렬 버튼 클릭하면 viewFiltersModal이 true로 잘 바뀜✔

✅ viewFiltersModal를 useSelector 이용해서 가져와야함
👉 왜냐, viewFiltersModal이 true일 때 모달을 보여줘야하기 때문🔥
state.modal 안에 있는 viewFiltersModal을 가져와야하기에 이렇게 해주면 됨👍

viewFiltersModal이 true일 때만 FiltersModal 컴포넌트를 렌더링 해줘야함💻
그러면 이렇게 FiltersModal이 뜨는 걸 볼 수 있음👀

얘도 똑같이 Modal.styles.js 에 있는 FixedContainer 사용할 것👌
▫ src>components>Modal>FiltersModal>FiltersModal.jsx

이런식으로 된 걸 볼 수 있음
우선 UI 부터 처리하고 기능도 만들어줄 것🙆♀️
🎈정렬 버튼 누르면 나오는 FiltersModal UI 해주기





TopBox➡정렬 & CLEAR 감싸는 부분

</TopBox>
<Box>
<div className='filters__subtitle'>
PRIORITY
</div>
</Box>
</Container>
TopBox 밑에 Box 컴포넌트 안에 div 태그 만들고
그 안에 className 만들고 PRIORITY 작성하기
<div className='filters__check'>
<input
type='radio'
name='filter'
value='low'
id='low'
/>
<label htmlFor='low'>
Low to High
</label>
</div>
이 부분한거니까 이제 High to Low도 만들어줘야함❗
<div className='filters__check'>
<input
type='radio'
name='filter'
value='high'
id='high'
/>
<label htmlFor='high'>
High to Low
</label>
</div>

이부분 만들어줘야함



👩🎨Box 스타일링 해주자❗



🔸user-select: none→ 사용자가 텍스트 드래그(선택)하지 못하게 하는 것
🙂FiltersModal ✖ 누르면 모달 닫아지게 하기
이렇게 하면 ✖누르면 모달창 닫아짐
...