-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[2주차 기본/심화/공유 과제] 관리자 페이지 #3
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
안녕하세요! 2주차 과제 고생 많으셨습니다 !
전체적으로 정말 깔끔하게 구현 잘 하셨다고 생각해요.
함수별로 기능을 적절하게 잘 나누고, js 파일로 분리한게 인상깊네요 👍👍
공유해주신 아티클도 잘 봤습니다 ! ! !
const checkEmpty = (fields) => { | ||
return fields.some((field) => field.trim() === ""); | ||
}; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
checkEmpty
까지 따로 분리한게 인상적이네요 👍👍
덕분에 addMember
함수의 역할이 더욱 명확해진 것 같아요 !
id: Date.now(), | ||
name, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
id를 Date.now()로 설정할 생각은 못했네요 대박입니다.
이번 과제서는 id가 충돌할 일이 없으니 좋은 방식인 것 같아요 👍
import { getMemberData, setMemberData } from "./dataUtils.js"; | ||
|
||
const checkEmpty = (fields) => { | ||
return fields.some((field) => field.trim() === ""); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
some() 내장함수의 활용 까지 정말 좋네요 👍
const deleteSelectedRows = () => { | ||
let memberData = getMemberData(); | ||
|
||
const checkboxes = document.querySelectorAll(".deleteCheckbox:checked"); | ||
const idsToDelete = Array.from(checkboxes).map((checkbox) => { | ||
const row = checkbox.closest("tr"); | ||
return parseInt(row.getAttribute("memberId"), 10); | ||
}); | ||
|
||
memberData = memberData.filter((member) => !idsToDelete.includes(member.id)); | ||
localStorage.setItem("membersData", JSON.stringify(memberData)); | ||
|
||
setMemberData(memberData); | ||
renderTable(); | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
멤버를 삭제하는 함수, 체크된 체크박스에서 삭제할 id를 가져오는 함수
두 가지로 분리해도 좋아보여요 !
export const getMemberData = () => { | ||
return JSON.parse(localStorage.getItem("membersData")) || []; | ||
}; | ||
|
||
export const setMemberData = (data) => { | ||
localStorage.setItem("membersData", JSON.stringify(data)); | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
자주 사용되는 부분을 유틸 함수로 분리한게 인상깊네요 👍
<span class="closeModalBtn">×</span> | ||
<div class="modalTitle">새 멤버 추가</div> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
HTML 엔티티 사용까지 디테일 대단합니다 ,, 👍
사실 뭔지 몰라서 찾아봤습니다. ㅎ
<div class="addModal"> | ||
<span class="closeModalBtn">×</span> | ||
<div class="modalTitle">새 멤버 추가</div> | ||
<form class="modalForm"> | ||
<div class="modalLable">이름</div> | ||
<input | ||
type="text" | ||
class="modalName" | ||
placeholder="이름을 입력하세요." | ||
/> | ||
<div class="modalLable">영문 이름</div> | ||
<input | ||
type="text" | ||
class="modalEngName" | ||
placeholder="영문이름을 입력하세요." | ||
/> | ||
<div class="modalLable">GitHub</div> | ||
<input | ||
type="text" | ||
class="modalGit" | ||
placeholder="GitHub ID를 입력하세요." | ||
/> | ||
<div class="modalLable">성별</div> | ||
<select class="modalGender"> | ||
<option disabled hidden selected>성별 선택</option> | ||
<option value="male">남자</option> | ||
<option value="female">여자</option> | ||
</select> | ||
<div class="modalLable">역할</div> | ||
<select class="modalRole"> | ||
<option disabled hidden selected>YB / OB 선택</option> | ||
<option value="YB">YB</option> | ||
<option value="OB">OB</option> | ||
</select> | ||
<div class="modalLable">1주차 금잔디조</div> | ||
<input | ||
type="number" | ||
placeholder="1주차 금잔디조 (1~9)를 입력하세요" | ||
min="1" | ||
max="9" | ||
class="modalWeek1" | ||
/> | ||
<div class="modalLable">2주차 금잔디조</div> | ||
<input | ||
type="number" | ||
placeholder="2주차 금잔디조 (1~9)를 입력하세요." | ||
min="1" | ||
max="9" | ||
class="modalWeek2" | ||
/> | ||
<button type="submit" class="modalSubmitBtn">추가</button> | ||
</form> | ||
</div> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
모달을 dialog가 아닌 div태그로 구현한 이유가 있나요? 궁금합니다 !
<script | ||
src="https://kit.fontawesome.com/c9218056bf.js" | ||
crossorigin="anonymous" | ||
></script> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
해당 script
태그만 head
안에 구현한 이유가 있나요 ?
height: 80px; | ||
padding: 0 20px; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
css파일 전부 rem이 아닌 px로 작성하셨는데 이유가 있나요?
px과 rem에 대한 성희님의 의견이 궁금합니다 !
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
js에 대해서 정말 많이 배우고 갑니다! 아예 모르고 있었던 함수들도 많고 전체적으로 코드가 명확하고 간결해서 보기 너무 편했습니다👍기능별로 정리하신 것도 배우고 갑니다!
z-index: 2; | ||
background-color: burlywood; | ||
display: grid; | ||
grid-template-columns: repeat(3, 1fr); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
오 repeat 함수로 열의 개수랑 각 열의 너비를 반복해서 설정하는 방법 배우고 갑니다!
.leftHeader { | ||
display: flex; | ||
justify-content: flex-start; | ||
} | ||
|
||
.centerHeader { | ||
display: flex; | ||
justify-content: center; | ||
} | ||
|
||
.rightHeader { | ||
display: flex; | ||
justify-content: flex-end; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
오... 헤더 3등분을 이렇게 left right center 로 나눠서 justify-content 로 정렬해주는 방법이 있었군요...! 눈에 잘 보여서 좋은 것 같아요!
import { getMemberData, setMemberData } from "./dataUtils.js"; | ||
|
||
const checkEmpty = (fields) => { | ||
return fields.some((field) => field.trim() === ""); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
오 some 이라는 내장함수가 있다는 것을 배웠어요. 배열 내에 빈 문자열 또는 공백만 있는 값이 포함되어 있는지 간단히 검사하는 것에 좋겠네요!
✨ 구현 기능 명세
💡 기본 과제
데이터
헤더
필터
(기본과제에서는 7개 모두 input으로 구현해도 괜찮음)
표
선택삭제
,추가
버튼이 위치선택삭제
버튼 클릭 시, 체크된 항목들 삭제추가
버튼 클릭 시, 항목 추가 모달 등장모달
닫기
버튼추가
버튼 클릭 시, 모달 닫히면 데이터 추가🔥 심화 과제
필터
표
모달
공유과제
제목: 함수형 프로그래밍 찍먹
링크 첨부 : https://wave-web.tistory.com/61
❗️ 내가 새로 알게 된 점
document.addEventListener("DOMContentLoaded", () => renderTable());
는 이벤트 발생 시점에 renderTable이 실행되지만document.addEventListener("DOMContentLoaded", renderTable());
은 이벤트 발생과 상관없이 renderTable이 바로 실행된다는 점을 알게되었습니다. 해당 결과가 다른 이유는 함수 호출 방식과 함수 참조의 차이 때문입니다. () => renderTable()는 화살표 함수이기 때문에 이벤트가 발생할 때 화살표 함수가 실행되고 그 안의 함수가 실행되지만, 후자의 코드는 바로 renderTable()을 호출하는 코드이기 때문에 바로 실행됩니다.❓ 구현 과정에서의 어려웠던/고민했던 부분
🥲 소요 시간
7h
🖼️ 구현 결과물
https://devveb.notion.site/2-12dd9673c22b80ff8fe7c8319aba0585