[0808] iPark project 피드백 수정

nikevapormax·2022년 8월 8일
0

TIL

목록 보기
86/116
post-custom-banner

iPark Project

피드백 사항 반영

  • 중간 발표가 끝난 후, 우리 팀이 배포한 서비스에 대해 사용자 피드백을 받아 중요한 부분을 선정해 수정하는 과정에 있다.
  • 물론 일주일이라는 시간 제한이 있고, 프론트앤드에 대한 부분이 많아 모든 것을 전부 다 반영하지는 못하겠지만 최대한 반영하기 위해 새벽까지 뛰고 있다.

공원 상세 페이지 길찾기 클릭 시 새창으로 이동

  • 아래의 부분을 누르게 되면 원래 해당 창에서 네이버 지도로 연결이 되도록 해놓았었다.
  • 다음과 같이 코드를 수정해 해당 버튼을 누르면 새창이 열리고, 그곳에서 네이버 지도의 길찾기를 사용할 수 있도록 변경해 페이지 이탈을 막았다.
    • target="_blank" 추가
var contentString = [
    '<div class="iw-inner">',
    '   <h5 style="color: green;">' + x["park_name"] + '</h5>',
    '   <a href="https://map.naver.com/v5/search/' + x["park_name"] +
    '?c=14134663.0407597,4519566.6272867,15,0,0,0,dh" style="text-decoration: none; color: green;" target="_blank">길찾기</a>',
    '</div>'
  ].join("")

토글의 공원 목록 나열 방식 변경

  • 원래 토글의 공원 나열 방식은 가나다 순으로 모든 공원을 쭉 나열하는 것이었다.
  • 사용자들의 반응은 아래와 같았다.
    • 가나다 순은 좋으나 모든 공원을 다 보여주기 대신 한글 자음으로 탭을 만들어 해당 탭에 해당하는 공원들을 확인하는 것이 나을 것 같다.
    • 해당 토글 안에 공원 이름 검색 등의 검색 기능도 있는 것도 좋을 것 같다.
  • 먼저 첫 번째 문제점을 아래와 같이 해결하였다.

  • 아직 css는 건드리지 않아 이쁘지는 않지만 기능적으로는 요구사항을 잘 반영했다고 생각한다.
  • 프론트앤드에 대해 배우지 않고 주먹구구식으로 한 것이어 코드는 개판이지만, 현재는 기능이 작동되고 사용자들의 요구사항을 하나 해결했다는 것이 중요하다 생각한다.
  • 코드는 아래와 같다.
    • querySelectorAllforEach를 활용해 하드코딩을 하지 않으려 했지만, 해당 기능들을 사용하면 addEventListener의 click을 무시하고 모든 데이터가 다 받아와 져서 결국 하드코딩 했다.
    • if 문을 확인하면 알 수 있듯이, div에 append 되는 아래 부분이 존재하지 않는다면 내용들을 붙여주고 존재한다면 자식노드들을 전부 없애주는 식으로 탭이 닫히는 효과를 주었다.
    • 한계점으로는 한 번 열고 닫으면 새로고침이 되지 않는다면 다시 열리지 않는다.
// 토글 공원 List 로드 
function showparkList(n, data) {
  const parkList = document.querySelector("#parkList" + n)

  if (parkList.childNodes.length == 0) {
    $.ajax({
      type: "POST",
      url: `${backendBaseUrl}/park/`,
      data: { data },
      success: function (response) {
        for (let i = 0; i < response.length; i++) {
          parkListTempHtml = `
            <li class="nav-item">
              <button class="nav-link active" aria-current="page" 
                style="border: none; background-color: transparent;" 
               token interpolation">${response[i].id})">${response[i].park_name}</button>
              <hr>
            </li>`
          $("#parkList" + n).append(parkListTempHtml)
        }
      }
    })
  } else {
    parkList.remove()
  }
}

회원가입에서 사용하지 않는 값 삭제

  • 사용하지 않는 값인 생년월일을 삭제하였다.
  • 생년월일에 대한 제목을 써주지 않아 사용자들이 불편해 했고, 나 또한 써야하는 것을 알면서도 다른 메뉴와의 밸런스 때문에 작성하지 못했었다.
  • 따라서 아무데서도 사용되지 않기 때문에 삭제하였다.

핸드폰 번호 기입 방식 변경

  • 기존에 핸드폰 번호를 010-0000-0000의 형식으로 받았었다.
  • 핸드폰 번호를 사용할 때 사용자마다 마음대로 입력하게 되면 에러가 날 것이라 생각해 그냥 통일해서 받자라는 생각이 있었다.
  • 하지만 사용자들에게서 오는 핸드폰번호를 저렇게 받냐는 피드백이 많았고, 추후에 입력 폼을 변경하면 되기 때문에 현재는 자유형식으로 받는 것으로 변경하였다.
  • 현재 사용하지 않기 때문에 백앤드에 존재하던 정규 표현식도 삭제해 놓았다.
  • 이 부분은 추후 핸드폰 번호를 입력하는 폼을 따로 사용하는 것으로 업그레이드 시킬 예정이다.

이메일 주소 select 반영

  • 사용자가 본인의 이메일 주소를 전부 다 입력하지 않아도 되도록 select tag를 사용했다.
  • 이로 인해 이메일 주소가 틀릴 일도 없어 에러 처리가 좀 더 수월해질 것이라 생각한다.
  • 코드는 아래와 같다.
<!-- 이메일 -->
      <div class="int-area" id="email-field">
        <input type="text" name="email" id="floatingInputEmail" autocomplete="off" required />
        <label for="floatingInputEmail">Email</label>
        <select id="emailSection">
          <option value="@naver.com">@naver.com</option>
          <option value="@gmail.com">@gmail.com</option>
          <option value="@kakao.com">@kakao.com</option>
          <option value="@daum.com">@daum.com</option>
          <option value="@nate.com">@nate.com</option>
          <option value="@outlook만.com">@outlook.com</option>
        </select>
      </div>

회원가입 시 틀린 항목에 대한 안내 메세지

  • 맨 처음 코드를 짤 때는 백앤드에서 하나씩 어떤 부분이 잘못 되었는지 메세지를 보내도록 했었다.
  • 그러나 중간에 해당 에러들 중 undefined로 나타나지는 친구들이 있어 그냥 하나로 퉁쳐서 에러 메세지를 보내기로 했다.
  • 이 부분에 대해 어디가 틀렸는지 알고 싶다는 피드백이 있어 이에 대해 수정해 보았다.
  • 하지만 아직 부족한 부분이 있다.
    • 잘못된 값을 넣고 다시 수정해 회원가입을 신청하는데, 이때도 다른 틀린 부분이 존재할 경우 맞는 부분에 메세지가 그대로 남아있게 된다.
  • 코드는 아래와 같다.
// 회원가입 
async function handleSignup() {
  const signupData = {
    username: document.getElementById("floatingInput").value,
    email: document.getElementById("floatingInputEmail").value + document.getElementById("emailSection").value,
    fullname: document.getElementById("floatingInputFullname").value,
    password: document.getElementById("floatingPassword").value,
    phone: document.getElementById("floatingPhone").value,
    region: document.getElementById("floatingRegion").value
  }

  const response = await fetch(`${backendBaseUrl}/user/`, {
    method: "POST",
    headers: {
      Accept: "application/json",
      "Content-type": "application/json"
    },
    body: JSON.stringify(signupData)
  })

  response_json = await response.json()
  if (response.status == 201) {
    window.location.replace(`${frontendBaseUrl}/login.html`)
  } else {
    const key = Object.keys(response_json)
    const error = Object.values(response_json)

    for (let i = 0; i < key.length; i++) {
      switch (key[i]) {
        case "username":
          const err_username = document.getElementById("username-field")
          err_username.removeChild(err_username.lastChild)
          var new_span = document.createElement("span")
          new_span.setAttribute("id", "error")
          new_span.innerText = error[i]
          err_username.appendChild(new_span)
          break
        case "email":
          const err_email = document.getElementById("email-field")
          err_email.removeChild(err_email.lastChild)
          var new_span = document.createElement("span")
          new_span.setAttribute("id", "error")
          new_span.innerText = error[i]
          err_email.appendChild(new_span)
          break
        case "fullname":
          const err_fullname = document.getElementById("fullname-field")
          err_fullname.removeChild(err_fullname.lastChild)
          var new_span = document.createElement("span")
          new_span.setAttribute("id", "error")
          new_span.innerText = error[i]
          err_fullname.appendChild(new_span)
          break
        case "password":
          const err_password = document.getElementById("password-field")
          err_password.removeChild(err_password.lastChild)
          var new_span = document.createElement("span")
          new_span.setAttribute("id", "error")
          new_span.innerText = error[i]
          err_password.appendChild(new_span)
          break
        case "phone":
          const err_phone = document.getElementById("phone-field")
          err_phone.removeChild(err_phone.lastChild)
          var new_span = document.createElement("span")
          new_span.setAttribute("id", "error")
          new_span.innerText = error[i]
          err_phone.appendChild(new_span)
          break
      }
    }
  }
}
  • region의 경우는 드롭다운으로 선택해야 해서 틀릴 수가 없어 넣지 않았다.
  • 엄청 하드코딩같이 보이긴 하지만 3 시간이라는 어마어마한 시간이 들어간 코드여서 추후 리팩토링을 진행할 예정이다.
  • 제일 시간이 많이 걸린 부분은 에러 메세지를 가져와 json으로 받고, 그것들을 key와 value로 나누는 것이었다.
const key = Object.keys(response_json)
const error = Object.values(response_json)
  • switch 문을 사용해 각 케이스마다 어떤 것을 할지 알려주었다. 분명히 반복되는 부분을 줄일 수 있다고 생각한다. 너무 더럽다.
  • 화면은 다음과 같이 나오게 된다.
  • 에러 메세지의 중복을 막기 위해 다음과 같이 가장 마지막 자식노드를 케이스가 시작될 때마다 지워주었다.
err_username.removeChild(err_username.lastChild)
profile
https://github.com/nikevapormax
post-custom-banner

0개의 댓글