iPark Project
피드백 사항 반영
- 중간 발표가 끝난 후, 우리 팀이 배포한 서비스에 대해
사용자 피드백을 받아 중요한 부분을 선정해 수정
하는 과정에 있다.
- 물론 일주일이라는 시간 제한이 있고, 프론트앤드에 대한 부분이 많아 모든 것을 전부 다 반영하지는 못하겠지만 최대한 반영하기 위해 새벽까지 뛰고 있다.
공원 상세 페이지 길찾기 클릭 시 새창으로 이동
- 아래의 부분을 누르게 되면 원래 해당 창에서 네이버 지도로 연결이 되도록 해놓았었다.
- 다음과 같이 코드를 수정해 해당 버튼을 누르면 새창이 열리고, 그곳에서 네이버 지도의 길찾기를 사용할 수 있도록 변경해 페이지 이탈을 막았다.
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는 건드리지 않아 이쁘지는 않지만 기능적으로는 요구사항을 잘 반영했다고 생각한다.
- 프론트앤드에 대해 배우지 않고 주먹구구식으로 한 것이어 코드는 개판이지만, 현재는 기능이 작동되고 사용자들의 요구사항을 하나 해결했다는 것이 중요하다 생각한다.
- 코드는 아래와 같다.
querySelectorAll
과 forEach
를 활용해 하드코딩을 하지 않으려 했지만, 해당 기능들을 사용하면 addEventListener
의 click을 무시하고 모든 데이터가 다 받아와 져서 결국 하드코딩 했다.
- if 문을 확인하면 알 수 있듯이, div에 append 되는 아래 부분이 존재하지 않는다면 내용들을 붙여주고 존재한다면 자식노드들을 전부 없애주는 식으로 탭이 닫히는 효과를 주었다.
- 한계점으로는 한 번 열고 닫으면 새로고침이 되지 않는다면 다시 열리지 않는다.
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)