-
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
KDT0_NamgungJongMin 직원 관리 서비스 #59
base: main
Are you sure you want to change the base?
Conversation
Add page's action Connect page to firebase authentication
add feature getting data from firebasestore
Fix main.html - example to create element Fix main/render.js - Modify innerHTML's class
…in/Yanolja_FE_JavaScript into KDT0_NamgungJongMin
저는 아직 로그인 구현을 못해서 잘 몰랐는데 |
이번 과제에선 배포가 요구사항에 없어서 하지 않았습니다 ㅠㅠ. 커뮤니티 올라오는 안 좋은 경우들 때문에 배포 무서워요.. ㅠㅠ 카드 등록되어있어서.. debounce는 저도 성능적으로 유의미한지에 대해선 잘 모르겠지만.. 저번 멘토링 때 멘토님께서 말씀해주신 부분을 잊어버리기 전에 직접 써보고 싶어서 한번 써봤어요.^^ 코드 리뷰 남겨주셔서 감사합니다! 우리 캡틴 항상 화이팅!! |
오... 로그인을 하지않으면 임의로 페이지 주소를 조작해서 넘어갈 수 없도록 구현하셨군요! |
debounce 에 대해서 처음 보게 되었는데요 |
파이어베이스에 정보를 저장한다기 보다는 firebase의 Authentication에 저장되어있는 이메일 비밀번호를 비교하여 유효성을 검증한 이후에 그 정보를 localstorage에 저장하는게 의도였습니다. 로그인 후에 나타날 페이지에서는 이 로컬스토리지의 정보를 바탕으로 로그인 페이지로의 이동을 제한하고, domcontentloaded 이벤트마다 로컬스토리지를 확인하여 로그인이 되었다는 정보가 있을 경우에만 페이지를 렌더링하게 하였습니다. 회원가입 기능을 안만들어서 헷갈리신거 같네요. 회원가입 페이지를 따로 만들지 않고 firebase내의 관리자 이메일을 직접 추가해놨습니다. |
이번 과제에 멋있는 아이디어를 적용하신 분들이 참 많은데 기능 개발에도 벅찼던 저는 그저 부끄러울 뿐입니다. 남은 기간동안 열심히 해서 따라가야죠. 오늘 특강에서 말씀해주신 것처럼 동경 또한 동력이 되니까요! |
역시.. 종민님의 서비스는 항상 볼때마다 배울점이 많습니다. |
안되요 안됩니다~~ 제꺼 참고하시면 큰일나요.ㅠ 폴더 구조부터 파일 분리나 코드 작성 전부 다른 분들 껄 볼 때마다 잘못되었다는 생각만 계속 드는 중입니다. 저희 자바스크립트 구현 강의를 다 보고 과제를 할걸 그랬어요 ㅠㅠ. 멘토님의 코드리뷰를 절실히 기다리는 중입니다. |
로그인 기능 잘 보았습니다~! 세부적인 부분까지 고려하셔서 참고할 부분이 많네요! 👍👍 |
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.
과제하시느라 고생하셨습니다 종민님~
코드도 적절히 작성해주셨고 디바운스도 잘사용해주신거같습니다~
다만 예외 처리 랑 비동기 코드에 대한 부분이 조금 아쉬워서 이부분에 대해 조금더 학습해주시면 좋을꺼같습니다~
const $list = document.getElementById('member-list'); | ||
|
||
// prettier-ignore | ||
const render = async (members, isSignin = false) => { |
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.
해당 함수에서는 비동기 코드가 안보여서 async 는 안쓰셔도 될꺼같습니다~
window.addEventListener('DOMContentLoaded', async e => { | ||
if (JSON.stringify(localStorage.getItem('isSignin')) === 'null') { | ||
location.replace('signin.html'); | ||
return; | ||
} | ||
|
||
await getAllMembers(state.members); | ||
|
||
await render(state.members); | ||
}); |
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.
async 함수내에 여러 await 이 있다면 await은 동기적으로 호출이 되게 됩니다 따라서 여기서는
getAllMembers 함수의 동작이 끝나야만 render 함수가 실행이 되는구조라 성능 과 사용자 경험에 있어서 비효율적일수도있습니다~
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.
리뷰 감사합니다 멘토님. 페이지가 첫 로드될 때 자바스크립트 내에 아무런 정보가 없기 때문에 먼저 데이터베이스에서 정보를 받아오고 그것을 바탕으로 페이지에 반영하려는 의도였습니다. 어떤식으로 바꿔야할지 잘 모르겠습니다 ㅠㅠ. 조금 더 힌트를 주실 수 있으실까요?
document.getElementById('main-search').addEventListener('focus', e => { | ||
e.target.placeholder = ''; | ||
}); | ||
|
||
// 검색 바에서 포커스 아웃될 시 value 값이 있으면 유지 없으면 placeholder 생성 | ||
document.getElementById('main-search').addEventListener('blur', e => { | ||
if (e.target.value) return; | ||
|
||
e.target.placeholder = '이름 또는 이메일로 검색하기'; | ||
}); |
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 에서 동일한 동작을 하고있기때문에 불필요해보입니다
물론 추가적인 로직이 있어야 되는 상황이라면 이벤트 리스너를 통하여 제어가 가능하지만 현재는 추가적인 로직이 없어서 자바스크립트로 placeholder를 제어할필요는 없어보입니다~
$allCheckbox.addEventListener('click', e => { | ||
const $checkboxes = document.querySelectorAll('input[type=checkbox]'); | ||
|
||
[...$checkboxes].forEach((checkbox, index) => { |
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.
nodeList에서는 기본적으로 forEach 메소드가 구현이 되어있어서 nodelist를 배열로 변환해서 forEach를 하지않으셔도될꺼가습니다~ 아래처럼 개선할수 있을꺼같습니다~
$checkboxes.forEach((checkbox, index) => {
checkbox.checked = index === 0 ? checkbox.checked : !checkbox.checked;
});
const [person, division, email, password, contact, picture] = $form; | ||
// 사진 firebase 올리고 profileUrl 할당 | ||
const profileUrl = await uploadImage(email.value, picture.files[0]); | ||
|
||
await addData(person.value, email.value, contact.value, division.value, profileUrl); | ||
|
||
location.replace('main.html'); |
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.
비동기 코드가 많을때에는 try/catch를 통한 예외처리를 하는것에 습관을 들여주시면 좋습니다~
// import { getStorage, ref, uploadBytes, getDownloadURL, deleteObject } from 'firebase/storage'; | ||
|
||
const firebaseConfig = { | ||
apiKey: 'AIzaSyCy7QYDgKpkn-0eH42AmxAki6u4DH1oGZ0', |
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.
추후에는 이러한 apikey는 환경변수로 관리해주시는걸 고민해주시면 좋을꺼같습니다~
👨💼직원 관리 서비스
💻사용 기술
❗ Notice
해당 README.md 파일의 gif 이미지는 녹화 문제 HDR오류로 인해 일정 채도 이하의 색상이 반영되지 않았다.
이미지 파일을 고르는 화면에서도 이미지 선택 과정이 녹화본엔 보이지 않는다.
|
Firebase
firebase를 서버로 활용하여 등록/수정/삭제되는 데이터들을 관리하고, 정보들을 받아와 그것을 기반으로 javascript 내에서 동적 렌더링 하였다.
📃페이지 기능
1) 로그인 페이지
OVERVIEW
설정한 정규식의 통과 여부를 판단하는 getter 함수를 지니고 결과를 return하는 schema 객체를 만든다.
schema를 통해 validation 할 시 lodash의 debounce 기능을 이용하여 input값의 변화마다 판별하는 것이 아닌 마지막 값의 변화를 기준으로
설정한 값 만큼의 시간이 지난 이후를 기점으로 팔별하여 불필요한 script의 동작을 줄인다.
각 항목의 validation이 통과 되었을 때에만 signin 버튼을 활성화한다.
로그인이 완료되기 전에는 다른 페이지로의 이동이 불가능하다.
페이지 이동 권한은 localstorage의 key값으로 현재 로그인 상태가 on이라는 것을 판단한 이후에 가능하다.
로그인 성공 후 페이지 이동 시 history에 등록되지 않고 페이지 자체를 replace시켜 뒤로가기가 불가능하다.
2) 리스트 페이지
OVERVIEW
각 페이지의 모든 정보들은 firebase에서 관리되며 렌더링 뿐만아니라 수정 삭제의 경우도 마찬가지로 firebase를 거쳐 데이터를 먼저 수정하고
수정한 데이터를 다시 받아와 동적 렌더링한다.
이미지 파일은 firebase storage에서 관리되고, 데이터들은 firestore 에서 객체로 관리된다.
임직원 등록 시 이름 / 이메일 / 휴대폰 번호 / 부서 등을 입력한 input의 값과 file url을 firebase를 거친 뒤 state 객체에 반영하고
다시 렌더링한다.
3) 상세 페이지
OVERVIEW
상세페이지도 리스트페이지와 마찬가지로 기본 컴포넌트의 값들은 비워둔 채 firebase의 데이터를 기반으로 동적으로 렌더링한다.
리스트 페이지에서 어떠한 사람을 클릭했는지에 대한 정보를 어떻게 상세 페이지로 넘겨줄 것인가?에 대한 고민
선택한 방법은 1번으로 주소창을 통해 명시적으로 어떤 사람을 클릭했는지 알 수 있다는 점과, 기존 주소창으로 넘겨주는 방법의 단점인 보안과 관련된 부분에서 문제가 없는 데이터라고 판단했기 때문에 주소창에 query로 넘겨주었다.
정보 변경 버튼을 클릭 시 disabled 상태의 input element들이 활성화 되고 변경이 가능하다. 변경 후 수정하기 버튼을 누르면 firebase의 데이터베이스를 수정하고 페이지를 다시 렌더링한다.
4) 공통
로그아웃
로그아웃 버튼을 누르게 되면 localstorage 내의 signin 정보의 키값을 비우고 로그인 페이지로 강제 이동된다.
이 때 history에는 추가되지 않으며 뒤로가기가 불가능하다.
반응형
모바일 퍼스트로 작업하고 media query를 이용해 데스크탑의 분기점 별로 스타일을 변화하였다.
USER FLOW