Skip to content
Open
12 changes: 12 additions & 0 deletions docs/specification.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# 기능 요구 사항
- 금액(Bill)을 입력할 수 있는 기능
- 금액(Bill)입력이 유효한지 판단하는 기능
- 팁을 선택할 수 있는 기능
- 5%, 10%, 15%, 25%, 50%, 사용자 설정
- custom 팁을 입력하는 기능
- custom 팁 입력이 유효한지 판단하는 기능
- 인원을 입력하는 기능
- 인원의 입력이 유효한지 판단하는 기능
- 인당 팁 금액을 계산해 보여주는 기능
- 인당 총 지불액을 계산해 보여주는 기능
- 내용을 모두 초기화 하는 기능

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

요구사항을 구체적으로 작성하는 건 좋은 습관인 것 같아요!

58 changes: 33 additions & 25 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,37 +8,45 @@

<title>Frontend Mentor | Tip calculator app</title>

<!-- Feel free to remove these styles or customise in your own stylesheet 👍 -->
<style>
.attribution { font-size: 11px; text-align: center; }
.attribution a { color: hsl(228, 45%, 44%); }

</style>
</head>
<body>

Bill

<p>Bill</p>
<input id="bill-input" placeholder="Bill"/>
Select Tip %
5%
10%
15%
25%
50%
Custom

Number of People

Tip Amount
/ person

Total
/ person

Reset

<div class="attribution">
Challenge by <a href="https://www.frontendmentor.io?ref=challenge" target="_blank">Frontend Mentor</a>.
Coded by <a href="#">Your Name Here</a>.
<div id="tip-percent-container">
<label>
5% <input class="percent-radio-btn" type="radio" name="percent" value="0.05"/>
</label>
<label>
10% <input class="percent-radio-btn" type="radio" name="percent" value="0.1"/>
</label>
<label>
15% <input class="percent-radio-btn" type="radio" name="percent" value="0.15"/>
</label>
<label>
25% <input class="percent-radio-btn" type="radio" name="percent" value="0.25"/>
</label>
<label>
50% <input class="percent-radio-btn" type="radio" name="percent" value="0.5"/>
</label>
<label>
<input id="custom-tip-input" type="text" ><input class="percent-radio-btn" type="radio" name="percent" value=""/>
</label>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

label에 대해 알아갑니다! label을 사용하는 건 생각하지 못한 방법이었네요..

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

radio 버튼이나 check 버튼등에 label을 사용하면, label안에 있는 요소를 클릭해도 선택이 됩니다.

</div>
<p>Number of People</p>
<input id="people-input">
<p>Tip Amount</p>
<p>/ person</p>
<div id="tip-amount-result">0.00</div>
<p>Total</p>
<p>/ person</p>
<div id="total-result">0.00</div>
<input type="button" value="Reset"/>
</body>
<script src="./src/index.js"></script>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

윤성님은 원래 html -> js -> css 순으로 코드를 작성하나요? 혹시 이런 경우 평소 css를 작성할 때 불편한 점은 없었는지 궁금합니다

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

변동이 필요없는 부분이나 변동이 일어나는 상위 태그는 미리 작성한 이후, 자바스크립트를 작성하는 편입니다. css의 개입이 필요하다면 중간중간 넣는 편인데, 이번에는 급하게 하느라 js에만 신경을 썼네요 .. (거기에 아직 미완입니다.)


</html>
77 changes: 77 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
const billInput = document.querySelector("#bill-input");
const peopleInput = document.querySelector("#people-input");
const tipAmountResult = document.querySelector("#tip-amount-result");
const totalResult = document.querySelector("#total-result");
const percentRadioBtns = document.querySelectorAll(".percent-radio-btn");
let bill = 0;
let people = 0;
let tipPercent = 0;
let tipPerPeople = 0;
let total = 0;
Comment on lines +6 to +10

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

이 미션에서는 페이지에서만 위와 같은 정보를 다루지만, 추후 다른 데이터와 명칭 등 다양하게 겹칠 수 있어 이 bill 데이터를 다루는 DTO같은 객체를 만들어 관리하면 더 좋을 것 같습니다.


const renderWarningStatus = () => {
// some logic...
};
Comment on lines +12 to +14

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

저는 이런 습관 정말 좋은 것 같습니다...분명 대부분의 IDE에서도 TODO: 같은 기능을 제공해주기도 하고, 실제로 저렇게 써 놓으면 다음날이 되어도 무슨 코드를 작성하려고 했는지 기억날것 같습니다.
저도 너무 주석을 경계하지 말고 다음번에는 이런식으로 작성해보도록 하겠습니다.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

허허 감사합니다


const isVaildInput = (target) => {
return !isNaN(target);
};
Comment on lines +16 to +18

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

airbnb에서도 이렇게 컨벤션을 지키라고 하더라고요!


const render = () => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

저도 이 부분에 대한 고민이 많았는데 이런 식으로 로직을 분리하셨군요!! 이게 더 가독성도 좋은 것 같네요

@2yunseong 2yunseong Nov 9, 2022

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

정확히 맞는 건 아니지만, 리액트에서 상태가 변경되면 render() 함수가 호출되는 걸 모방했습니다 ~!

const vaildCheckList = [bill, people];
if (!vaildCheckList.every((element) => isVaildInput(element))) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

every에 대해서는 처음 알았네요! 메모해갑니다..

// handle bad input ...
console.log("bad bill input!");
}
calcResult();
renderTipPerPeople();
renderTotal();
};

const printState = () => {
console.log("bill:", bill);
console.log("people:", people);
console.log("tip:", tipPercent);
};
Comment on lines +31 to +35

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

git에 올릴때는 console.log를 빼주시는 것이 더 깔끔한 코드가 될 것 같습니다.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

맞네요 좋은 피드백 감사드립니다 👍 👍 👍


const onChangeBill = (e) => {
bill = +e.target.value;
render();
};

const onChangePeople = (e) => {
people = +e.target.value;
render();
};

const onChangePercentRadio = (e) => {
tipPercent = +e.target.value;
render();
};

const calcResult = () => {
calcTipPerPeople();
calcTotal();
};

const calcTipPerPeople = () => {
tipPerPeople = (bill * tipPercent) / people;
};

const renderTipPerPeople = () => {
tipAmountResult.innerText = tipPerPeople;
};

const calcTotal = () => {
total = bill / people;
};

const renderTotal = () => {
totalResult.innerText = total;
};

billInput.addEventListener("change", onChangeBill);
peopleInput.addEventListener("change", onChangePeople);
for (const percentRadioBtn of percentRadioBtns) {
percentRadioBtn.addEventListener("change", onChangePercentRadio);
}