Skip to content
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 jang ho jin #61

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
Open

Kdt0 jang ho jin #61

wants to merge 12 commits into from

Conversation

LeHiHo
Copy link

@LeHiHo LeHiHo commented Aug 18, 2023

직원 관리 시스템

배포주소 :https://frolicking-meerkat-ab332e.netlify.app/

직원등록

ezgif com-video-to-gif (2)

직원삭제

ezgif com-video-to-gif (1)

직원수정

ezgif com-video-to-gif (3)

userflow

userflow

@netlify
Copy link

netlify bot commented Aug 18, 2023

Deploy Preview for frolicking-meerkat-ab332e ready!

Name Link
🔨 Latest commit f19169e
🔍 Latest deploy log https://app.netlify.com/sites/frolicking-meerkat-ab332e/deploys/64e5725d0fbc4f00088a6c80
😎 Deploy Preview https://deploy-preview-61--frolicking-meerkat-ab332e.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

Copy link

@noSPkeepgoing noSPkeepgoing left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

중간에 firebase로 다시 짜느라 힘드셨을텐데,, 필수 기능 모두 구현하신 거 대단해요! 고생 많이 하셨습니당✨👏

Comment on lines +4 to +6
function toggleClassOnElement(element, className) {
element?.classList.toggle(className);
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오 엄청 다양한 곳에서 활용할 수 있게 함수로 묶으셨네요. 호진님의 세심함이 잘 느껴지는 부분인 거 같아요.✨

});

document.querySelector(".staff-box__delete").addEventListener("click", async function () {
const selectedElements = document.querySelectorAll(".staff-box__item.active.select");

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저라면 선택됐다는 것을 알 수 있는 클래스는 select니까, active는 제외하고 .staff-box_item.select이런 식으로 작성했을 거 같아요!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

하핫.. 저도 그렇게 구현하려했는데 사실 수정모드일때 staff-box_item.modify가 되고 거기다가 선택했을땐 staff-box_item.modify.select로 했습니다.
멍청이 처럼 코드짜서
staff-box_item.select로 하면 수정모드랑 제거모드를 구별할수 없게되버립니다.ㅠㅠ

Comment on lines +53 to +58
modalBox.querySelector("input[name='employeeNumber']").value = data.employeeNumber;
modalBox.querySelector("input[name='userName']").value = data.userName;
modalBox.querySelector("select[name='dept']").value = data.dept;
modalBox.querySelector("select[name='position']").value = data.position;
modalBox.querySelector("input[name='userNumber']").value = data.userNumber;
modalBox.querySelector(".modal-box__inputImg img").src = data.imageUrl;
Copy link

@noSPkeepgoing noSPkeepgoing Aug 23, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const {employeeNumber, userName, dept, position, userNumber, imageUrl } = data; 이런식으로 변수를 가져오거나,

modalBox.querySelectorAll('input')
    .forEach( el => { 
        const name = el.name;
        el.value = data[name];
});

요런식으로하면 코드를 작성해보면 어떨까요?! 뭔가 충분히 코드를 줄일 수 있는 방법이 있을 거 같은데 좋은 생각이 딱히 안 떠오르네요,,🥲

previouslySelected.classList.remove("select");
}

clickedItem.classList.add("select");

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여기 부분인지는 확실치 않긴한데, 직원 관리에서 select했던 클래스가 유지되면서 직원삭제에서도 반영되더라구요!
사실 제가 선택된지 모르고 삭제해버리는 참사를 일으켜 버렸어요..ㅎ👀💦

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

예외처리 리팩토링 할때 좀더 세심히 해보겠습니다..

Comment on lines +31 to +34
let file = document.querySelector("#image").files[0];
let storageRef = storage.ref();
let savePath = storageRef.child("image/" + file.name);
let uploadImage = savePath.put(file);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

사용자가 빈칸으로 제출해서 한 번 오류가 나면 다시 재입력해도 아무런 동작을 하지 않더라구요! 값이 있는지 없는지 미리 체크하는 로직이 추가되면 더 좋을 거 같습니당

@kyungkyuBae
Copy link

저는 항상 사용자의 편의성에서 더 좋다거나 웹의 성능을 비교 했을때 드라마틱한 차이가 없을것같다면
항상 자신과 타협해서 쉬운 쪽으로만 코드를 짜려고하는데
호진님의 코드를 보면 난이도를 먼저 보지않고,
사용자의 편의성,코드의 가독성,코드의 성능 모두를 고려하셔서 어렵더라도 도전하시고 코드를 짜시는게 배워가고싶어요
이번 aws도 스터디원 모두 쉬운 firebase로 돌아갈때 aws로도 해보시고 firebase로도 하시는걸 보고 정말 대단하다고 느꼈습니다.
코드를 봐도 저는 의식의 흐름대로 코드르 짜고 냅두는 경우가 많은데 호진님 코드를 보면 가독성을 위해서
여러 문법들을 사용하셔서 코드의 숫자를 최대한 줄이고 가독성 좋게 하려고 하시는게 보이는 것 같아서 배워가겠습니다.

Copy link
Member

@suehub suehub left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

코드의 가독성에 항상 신경을 많이 쓰시는 것 같습니다. UI도 고민을 많이 하신 것이 보이고, 파이어베이스로 바꾸시느라 고생 많으셨습니다~👍
현재 웹에서 모달창의 높이가 맞지 않는데 이 부분과 반응형만 추가한다면 더 퀼리티있는 관리 페이지가 될 것 같아요!

Comment on lines +45 to +55
if (employeeData && employeeData.imageUrl) {
const imageUrl = employeeData.imageUrl;
const cleanUrl = imageUrl.split("?")[0];
const imageKey = cleanUrl.split("%2F").pop();
const imageKeyDecoded = decodeURIComponent(imageKey);

try {
await storage.child(`image/${imageKeyDecoded}`).delete();
} catch (error) {
console.error("Error processing imageUrl for employee:", id, error);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 부분이 storage에 업로드된 이미지까지 삭제하기 위한 코드로 이해했는데 맞을까요??

}

const toggleEmployeeModify = () => {
[...document.querySelectorAll(".staff-box__item")].forEach((item) => toggleClassOnElement(item, "modify"));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

querySelectorAll 로 선택한 엘리멘트들을 spread operator로 바로 사용할 수 있게 작성하셨군요! 생각하지 못했는데 배워갑니다! 👍

const snapshot = await db.collection("user").get();
snapshot.forEach((doc) => {
const staffElement = createStaffTemplate(doc.data(), doc);
staffBox.insertAdjacentHTML("beforeend", staffElement);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

insertAdjacentHTML() 메소드를 처음 봤는데, '텍스트를 파싱하여 결과 노드들을 지정된 위치의 DOM 트리에 삽입'하는 메소드면 append()와 같은 역할을 하는 것으로 이해하면 될까요?

@humnyenye
Copy link

늘 다양한 시도를 해보시는 것 같아서 멋집니다. 고민하면서 코드를 짜는게 항상 보이니까 저도 열심히 해야지 하는 힘을 얻습니다.

Copy link
Member

@marshallku marshallku left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

고생하셨습니다!

반복되는 로직을 묶고, 모듈화를 진행해보면 더욱 좋을 것 같습니다!

UX적으로는

  1. 직원 삭제 버튼을 누르면 다시 직원 삭제 버튼으로 취소할 수 있는 기능
  2. 직원 삭제 이전 확인
  3. 직원 클릭 시 해당 직원 정보만 확인 (모달 재사용)
    정도가 있었으면 더 좋았을 것 같아요.


</head>

<body masked>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

class="masked"를 의도하셨던 건가요?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

넵 저렇게 작성해도 동작하는거 같아서 넘어갔던것 같습니다.
해당 부분 수정했습니다!

<div class="navbar__logo">
<i class="fa-solid fa-users-rectangle"></i>
<a href="">직원 관리 시스템</a>
<a href="#" class="navbar__tooglebtn">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여기는 <button>을 사용하는 게 좀 더 정확해 보입니다!


</div>
<div class="modal-box__inputImg">
<img src="" alt="">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

<img>를 모달이 보일 때 동적으로 만드는 게 낫지 않을까요?

<div>
<div>
<label for="userName">이름</label>
<input type="text" name="userName" id="userName" placeholder="홍길동">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

class 등 속성과 마찬가지로 id에도 kebab-case를 사용하는 게 일반적입니다.

<div>
<label for="dept">부서</label>
<select name="dept" id="dept">
<option value="인사">인사</option>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If no value attribute is included, the value defaults to the text contained inside the element

MDN을 참고해보시면, value 값은 기본적으로 element 내부 텍스트로 잡혀있습니다. 이 상황에는 value를 작성하지 않았어도 되지 않을까요?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

앗 해당부분 수정하겠습니다!

Comment on lines +3 to +5
function toggleClassOnElement(element, className) {
element?.classList.toggle(className);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

toggleClassOnElement를 여러 파일에서 구현해뒀는데, 한 군데만 구현하고 import하는 게 낫지 않을까요?

const clickedItem = event.target.closest(".staff-box__item.modify");

if (clickedItem && clickedItem.classList.contains("modify")) {
const previouslySelected = document.querySelector(".staff-box__item.modify.select");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clickedItem.classList.contains("select") 처럼도 작성할 수 있지 않을까요?

const updatedData = {};
formData.forEach((value, key) => (updatedData[key] = value));

let file = document.querySelector("#image").files[0];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

재할당 되지 않는 변수로 보이네요~
추가로 getElementById를 사용해도 될 것 같습니다.

Comment on lines +180 to +184
const imageUrl = employeeData.imageUrl;
const cleanUrl = imageUrl.split("?")[0];
const imageKey = cleanUrl.split("%2F").pop();
const imageKeyDecoded = decodeURIComponent(imageKey);
console.log(imageKeyDecoded);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이런 로직도 공통화했으면 좋았을 것 같네요!

const db = firebase.firestore();
const storage = firebase.storage();

$(".submitButton").click(function (event) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 함수에서만 갑자기 jQuery가 사용된 이유가 있을까요...?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants