From 262bf777529f5fdd4e8be155b53c97976382a76e Mon Sep 17 00:00:00 2001 From: ohtmm Date: Mon, 11 Dec 2023 15:20:23 +0900 Subject: [PATCH 1/8] =?UTF-8?q?2week:=20=EC=9E=A5=EB=B0=94=EA=B5=AC?= =?UTF-8?q?=EB=8B=88=20=ED=8C=9D=EC=97=85=20UI=20=20=EC=84=B8=ED=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/2week/app.js | 38 +++++++++++++++++++++++ src/2week/assets/css/app.css | 58 ++++++++++++++++++++++++++++++++++++ src/2week/index.html | 8 +++++ 3 files changed, 104 insertions(+) diff --git a/src/2week/app.js b/src/2week/app.js index f20346a..4c83a2f 100644 --- a/src/2week/app.js +++ b/src/2week/app.js @@ -1,6 +1,43 @@ var shopping_cart = []; var shopping_cart_total = 0; +// cart layer +const cartLayer = document.getElementById('cart-layer'); +const cartList = document.getElementById('cart-list'); +const cartIcon = document.querySelector('.carts>.icons'); + +function open_cart () { + cartLayer.style.display = 'block' +} + +function close_cart(){ + cartLayer.style.display = 'none' +} + +function show_cart_list() { + cartList.innerHTML= shopping_cart.map( item => ` +
+ ${item.category} +

${item.name}

+

${item.price}

+
+ ` +) +} + +cartIcon.addEventListener('click', ()=>{ + open_cart(); + show_cart_list(); +}) + +cartLayer.addEventListener('click', (e)=>{ + if(e.target !== cartLayer) return; + close_cart() ; +}) + + + +// items document.querySelectorAll('button').forEach(button => button.addEventListener('click', ({ target }) => { const name = target.parentNode.querySelector('.menu-name').textContent; @@ -66,3 +103,4 @@ function update_tax_dom() { function set_tax_dom(value) { document.querySelector('.total-price').textContent = value; } + diff --git a/src/2week/assets/css/app.css b/src/2week/assets/css/app.css index f95b45b..8ff0b03 100644 --- a/src/2week/assets/css/app.css +++ b/src/2week/assets/css/app.css @@ -21,6 +21,8 @@ body { flex-direction: column; } + + h1 { display: inline-block; background-color: #333; @@ -111,4 +113,60 @@ span { p, .price { height: 20px; +} + + +/* cart layer */ +#cart-layer{ + display: none; + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: #21252940; +} + +#cart-layer_inner{ + width: 100%; + height: 100%; + padding: 16px; +} + +#cart-layer_inner>h2{ + font-size: large; + margin-bottom: 16px; +} + +#cart-list{ + float: right; + width: 50%; + height:100%; + background-color: #fff; +} + +#cart-list .cart-item{ + width: 100%; + display: flex; + gap: 4px; + background-color: #00585760; + border-radius: 8px; + padding: 16px; + +} + +#cart-list .cart-item>.name{ + width: 100%; + font-size: 14px; + margin-bottom: 8px; +} + +#cart-list .cart-item>.category{ + width: 24px; + height: 24px; +} + + +#cart-list .cart-item>.price{ + font-weight: 700; } \ No newline at end of file diff --git a/src/2week/index.html b/src/2week/index.html index c4111e9..480711c 100644 --- a/src/2week/index.html +++ b/src/2week/index.html @@ -18,7 +18,15 @@

FECrash 카페

0원 +
+
+

장바구니

+
+
+
+
+
item From e76131f5ba5aaaaa4f62f7c2508da0227d3f9f89 Mon Sep 17 00:00:00 2001 From: jiyoung Date: Tue, 12 Dec 2023 07:54:27 +0900 Subject: [PATCH 2/8] =?UTF-8?q?week2:=20calc=20total=20=EC=9C=A0=ED=8B=B8?= =?UTF-8?q?=EB=A6=AC=ED=8B=B0=20=ED=95=A8=EC=88=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/2week/app.js | 53 +++--- src/2week/assets/css/app.css | 53 +++--- src/2week/index.html | 328 ++++++++++++++++++++++------------- 3 files changed, 261 insertions(+), 173 deletions(-) diff --git a/src/2week/app.js b/src/2week/app.js index 4c83a2f..f91cfe7 100644 --- a/src/2week/app.js +++ b/src/2week/app.js @@ -2,50 +2,60 @@ var shopping_cart = []; var shopping_cart_total = 0; // cart layer -const cartLayer = document.getElementById('cart-layer'); +const cartLayer = document.getElementById('cart-layer'); const cartList = document.getElementById('cart-list'); const cartIcon = document.querySelector('.carts>.icons'); -function open_cart () { - cartLayer.style.display = 'block' +function open_cart() { + cartLayer.style.display = 'block'; } -function close_cart(){ - cartLayer.style.display = 'none' +function close_cart() { + cartLayer.style.display = 'none'; } function show_cart_list() { - cartList.innerHTML= shopping_cart.map( item => ` + cartList.innerHTML = shopping_cart.map( + (item) => `
${item.category}

${item.name}

${item.price}

` -) + ); } -cartIcon.addEventListener('click', ()=>{ +cartIcon.addEventListener('click', () => { open_cart(); show_cart_list(); -}) +}); -cartLayer.addEventListener('click', (e)=>{ - if(e.target !== cartLayer) return; - close_cart() ; -}) +cartLayer.addEventListener('click', (e) => { + if (e.target !== cartLayer) return; + close_cart(); +}); +function formatCurrencyToNumber(priceText) { + const regex = /,/g; + return parseFloat(priceText.replace(regex, '')); +} +function formatNumberToCurrency(priceNum) { + return priceNum; +} -// items -document.querySelectorAll('button').forEach(button => +// items +document.querySelectorAll('button').forEach((button) => button.addEventListener('click', ({ target }) => { const name = target.parentNode.querySelector('.menu-name').textContent; const category = target.parentNode.querySelector('.category').textContent; - const price = target.parentNode.querySelector('.price').textContent; + const price = formatCurrencyToNumber( + target.parentNode.querySelector('.price').textContent + ); add_item_to_cart({ name, category, price }); - }), + }) ); function add_item_to_cart(item) { @@ -60,13 +70,13 @@ function calc_cart_total() { var item = shopping_cart[i]; shopping_cart_total += item.price; } - set_cart_total_dom(); + set_cart_total_dom(shopping_cart_total); update_shipping_icons(); update_tax_dom(); } -function set_cart_total_dom() { - document.querySelector('.total-price').textContent = shopping_cart_total; +function set_cart_total_dom(total) { + document.querySelector('.total-price').textContent = total; } function update_shipping_icons() { @@ -97,10 +107,9 @@ function get_buy_buttons_dom() { } function update_tax_dom() { - set_tax_dom(shopping_cart_total * 0.1); + set_tax_dom(shopping_cart_total); } function set_tax_dom(value) { document.querySelector('.total-price').textContent = value; } - diff --git a/src/2week/assets/css/app.css b/src/2week/assets/css/app.css index 8ff0b03..7e6f4ae 100644 --- a/src/2week/assets/css/app.css +++ b/src/2week/assets/css/app.css @@ -4,7 +4,7 @@ } body { - background-color: #F2EEE9; + background-color: #f2eee9; font: normal 13px/1.5 Georgia, Serif; color: #333; } @@ -21,8 +21,6 @@ body { flex-direction: column; } - - h1 { display: inline-block; background-color: #333; @@ -69,7 +67,7 @@ button { border: none; border-radius: 8px; padding: 4px 14px; - background-color: #00A29E; + background-color: #00a29e; color: #ffffff; text-transform: uppercase; float: right; @@ -84,7 +82,7 @@ button { } button:hover { - background-color: #00C6C2; + background-color: #00c6c2; } button:active { @@ -97,7 +95,8 @@ span { .shopping-cart { display: inline-block; - background: url('http://cdn1.iconfinder.com/data/icons/jigsoar-icons/24/_cart.png') no-repeat 0 0; + background: url('http://cdn1.iconfinder.com/data/icons/jigsoar-icons/24/_cart.png') + no-repeat 0 0; width: 24px; height: 24px; margin: 0 10px 0 0; @@ -106,18 +105,18 @@ span { .category { border-radius: 8px; background-color: #fff; - border: 1px solid #00A29E; - color: #00A29E; + border: 1px solid #00a29e; + color: #00a29e; padding: 6px; } -p, .price { +p, +.price { height: 20px; } - /* cart layer */ -#cart-layer{ +#cart-layer { display: none; position: fixed; top: 0; @@ -127,46 +126,44 @@ p, .price { background-color: #21252940; } -#cart-layer_inner{ - width: 100%; +#cart-layer_inner { + position: absolute; + top: 0; + right: 0; + width: 40%; height: 100%; - padding: 16px; + background-color: #fff; } -#cart-layer_inner>h2{ +#cart-layer_inner > h2 { font-size: large; + padding: 16px; margin-bottom: 16px; } -#cart-list{ - float: right; - width: 50%; - height:100%; - background-color: #fff; +#cart-list { + padding: 16px; } -#cart-list .cart-item{ - width: 100%; +#cart-list .cart-item { display: flex; gap: 4px; background-color: #00585760; border-radius: 8px; padding: 16px; - } -#cart-list .cart-item>.name{ +#cart-list .cart-item > .name { width: 100%; font-size: 14px; margin-bottom: 8px; } -#cart-list .cart-item>.category{ +#cart-list .cart-item > .category { width: 24px; height: 24px; } - -#cart-list .cart-item>.price{ +#cart-list .cart-item > .price { font-weight: 700; -} \ No newline at end of file +} diff --git a/src/2week/index.html b/src/2week/index.html index 480711c..3ab5549 100644 --- a/src/2week/index.html +++ b/src/2week/index.html @@ -1,130 +1,212 @@ - - - - - - FECrash 카페 - - - - - -
-

FECrash 카페

-
- - 0원 -
- -
-
-

장바구니

-
-
+ + + + + FECrash 카페 + + + + + +
+

FECrash 카페

+
+ + 0원
-
-
-
-
- item -

C오늘의 커피

-

가격: 1,000원

- -
-
- item -

C나이트로 바닐라 크림

- -

가격: 3,500원 -

- -
-
- item -

C나이트로 콜드 브루

- -

가격: 4,000원 -

- -
-
- item -

C돌체 콜드 브루

- -

가격: 3,900원 -

- -
-
- item -

C자바 칩 프라푸치노

- -

가격: 5,200원 -

- -
-
- item -

C민트 콜드 브루

- -

가격: 4,800원 -

- -
-
- item -

C바닐라 크림 콜드 브루

- -

가격: 4,300원 -

- -
-
- item -

C아이스 토피넛 라떼

- -

가격: 5,500원 -

- -
-
- item -

C제주 비저링 콜드 브루

- -

가격: 6,000원 -

- -
-
- item -

B라즈베리 쇼콜라

- -

가격: 7,000원 -

- -
-
- item -

B클래식 스콘

- -

가격: 3,300원 -

- +
+
+

장바구니

+
+
-
- item -

B티라미수 크림 데니쉬

- -

가격: 7,200원 -

- +
+ +
+
+ item +

+ C오늘의 커피 +

+

가격: 1,000원

+ +
+
+ item +

+ C나이트로 바닐라 크림 +

+ +

가격: 3,500원

+ +
+
+ item +

+ C나이트로 콜드 브루 +

+ +

가격: 4,000원

+ +
+
+ item +

+ C돌체 콜드 브루 +

+ +

가격: 3,900원

+ +
+
+ item +

+ C자바 칩 프라푸치노 +

+ +

가격: 5,200원

+ +
+
+ item +

+ C민트 콜드 브루 +

+ +

가격: 4,800원

+ +
+
+ item +

+ C바닐라 크림 콜드 브루 +

+ +

가격: 4,300원

+ +
+
+ item +

+ C아이스 토피넛 라떼 +

+ +

가격: 5,500원

+ +
+
+ item +

+ C제주 비저링 콜드 브루 +

+ +

가격: 6,000원

+ +
+
+ item +

+ B라즈베리 쇼콜라 +

+ +

가격: 7,000원

+ +
+
+ item +

+ B클래식 스콘 +

+ +

가격: 3,300원

+ +
+
+ item +

+ B티라미수 크림 데니쉬 +

+ +

가격: 7,200원

+ +
-
- - - - \ No newline at end of file + + + From c04a1ce1e0ecc6557c9cf12313bc4614dda6441b Mon Sep 17 00:00:00 2001 From: ohtmm Date: Wed, 13 Dec 2023 18:11:19 +0900 Subject: [PATCH 3/8] =?UTF-8?q?2week:=20=EC=9E=A5=EB=B0=94=EA=B5=AC?= =?UTF-8?q?=EB=8B=88=20total=20=EC=84=B8=ED=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/2week/app.js | 48 +++-- src/2week/assets/css/app.css | 9 + src/2week/index.html | 338 ++++++++++++++--------------------- 3 files changed, 174 insertions(+), 221 deletions(-) diff --git a/src/2week/app.js b/src/2week/app.js index f91cfe7..d87ea09 100644 --- a/src/2week/app.js +++ b/src/2week/app.js @@ -42,7 +42,7 @@ function formatCurrencyToNumber(priceText) { } function formatNumberToCurrency(priceNum) { - return priceNum; + return priceNum.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")+'원'; } // items @@ -64,41 +64,40 @@ function add_item_to_cart(item) { calc_cart_total(); } +// Q : 왜 cart_total 과 tax DOM 업데이트를 2번 해줘야 할까? function calc_cart_total() { shopping_cart_total = 0; for (var i = 0; i < shopping_cart.length; i++) { var item = shopping_cart[i]; shopping_cart_total += item.price; } - set_cart_total_dom(shopping_cart_total); + set_total_price_dom(shopping_cart_total); + update_tax_dom(shopping_cart_total); update_shipping_icons(); - update_tax_dom(); } -function set_cart_total_dom(total) { - document.querySelector('.total-price').textContent = total; -} function update_shipping_icons() { var buy_buttons = get_buy_buttons_dom(); for (var i = 0; i < buy_buttons.length; i++) { var item = buy_buttons[i]; console.log(item); - if (item.price + shopping_cart_total >= 20) item.show_free_shopping_icon(); - else item.hide_free_shopping_icon(); + if (item.price + shopping_cart_total >= 20000) item.show_free_shipping_icon(); + else item.hide_free_shipping_icon(); } } +// Q: shopping_cart를 복제하고, 무료 배송 아이콘을 보여주는 기능이 추가된 객체 배열. function get_buy_buttons_dom() { var buttons = []; - + const free_shipping_icon = document.querySelector('.free-shipping'); for (var i = 0; i < shopping_cart.length; i++) { var item = shopping_cart[i]; - item.show_free_shopping_icon = function () { - console.log('DOM 의 아이콘을 보여줍니다'); + item.show_free_shipping_icon = function () { + free_shipping_icon.classList.remove('hidden'); }; - item.hide_free_shopping_icon = function () { - console.log('DOM 의 아이콘을 숨깁니다'); + item.hide_free_shipping_icon = function () { + free_shipping_icon.classList.add('hidden') }; buttons.push(item); } @@ -106,10 +105,25 @@ function get_buy_buttons_dom() { return buttons; } -function update_tax_dom() { - set_tax_dom(shopping_cart_total); +// tax를 더한다는 것을 제외하면 set_calc_total_dom 동작과 같음, calc+total 을 관리하는 돔으로 통합하는 건 ? +function update_tax_dom( cartTotal) { + const tax = calc_tax(cartTotal) + set_total_price_dom(cartTotal + tax); } -function set_tax_dom(value) { - document.querySelector('.total-price').textContent = value; +function set_total_price_dom(totalNum){ + document.querySelector('.total-price').textContent = formatNumberToCurrency(totalNum); } + +// function set_tax_dom(value) { +// document.querySelector('.total-price').textContent = formatNumberToCurrency(value); +// } + +// function set_cart_total_dom(total) { +// document.querySelector('.total-price').textContent = formatNumberToCurrency(total); +// } + + +function calc_tax(total){ + return total * 0.1 +} \ No newline at end of file diff --git a/src/2week/assets/css/app.css b/src/2week/assets/css/app.css index 7e6f4ae..acc03b0 100644 --- a/src/2week/assets/css/app.css +++ b/src/2week/assets/css/app.css @@ -93,6 +93,10 @@ span { float: right; } +.hidden { + display: none; +} + .shopping-cart { display: inline-block; background: url('http://cdn1.iconfinder.com/data/icons/jigsoar-icons/24/_cart.png') @@ -102,6 +106,11 @@ span { margin: 0 10px 0 0; } +.free-shipping{ + text-transform: uppercase; + color: red; +} + .category { border-radius: 8px; background-color: #fff; diff --git a/src/2week/index.html b/src/2week/index.html index 3ab5549..430d3ca 100644 --- a/src/2week/index.html +++ b/src/2week/index.html @@ -1,212 +1,142 @@ - - - - - FECrash 카페 - - - - - -
-

FECrash 카페

-
- + + + + + + FECrash 카페 + + + + + +
+

FECrash 카페

+
+ /span> 0원 +
+ +
+
+

장바구니

+
+
+
+
+ +
+
+ item +

+ C오늘의 커피 +

+

가격: 1,000원

+
+
+ item +

+ C나이트로 바닐라 크림 +

-
-
-

장바구니

-
-
+

가격: 3,500원

+
-
- -
-
- item -

- C오늘의 커피 -

-

가격: 1,000원

- -
-
- item -

- C나이트로 바닐라 크림 -

- -

가격: 3,500원

- -
-
- item -

- C나이트로 콜드 브루 -

- -

가격: 4,000원

- -
-
- item -

- C돌체 콜드 브루 -

- -

가격: 3,900원

- -
-
- item -

- C자바 칩 프라푸치노 -

- -

가격: 5,200원

- -
-
- item -

- C민트 콜드 브루 -

- -

가격: 4,800원

- -
-
- item -

- C바닐라 크림 콜드 브루 -

- -

가격: 4,300원

- -
-
- item -

- C아이스 토피넛 라떼 -

- -

가격: 5,500원

- -
-
- item -

- C제주 비저링 콜드 브루 -

- -

가격: 6,000원

- -
-
- item -

- B라즈베리 쇼콜라 -

- -

가격: 7,000원

- -
-
- item -

- B클래식 스콘 -

- -

가격: 3,300원

- -
-
- item -

- B티라미수 크림 데니쉬 -

- -

가격: 7,200원

- -
+
+ item +

+ C나이트로 콜드 브루 +

+ +

가격: 4,000원

+ +
+
+ item +

+ C돌체 콜드 브루 +

+ +

가격: 3,900원

+ +
+
+ item +

+ C자바 칩 프라푸치노 +

+ +

가격: 5,200원

+ +
+
+ item +

+ C민트 콜드 브루 +

+ +

가격: 4,800원

+ +
+
+ item +

+ C바닐라 크림 콜드 브루 +

+ +

가격: 4,300원

+ +
+
+ item +

+ C아이스 토피넛 라떼 +

+ +

가격: 5,500원

+ +
+
+ item +

+ C제주 비저링 콜드 브루 +

+ +

가격: 6,000원

+ +
+
+ item +

+ B라즈베리 쇼콜라 +

+ +

가격: 7,000원

+ +
+
+ item +

+ B클래식 스콘 +

+ +

가격: 3,300원

+ +
+
+ item +

+ B티라미수 크림 데니쉬 +

+ +

가격: 7,200원

+
- - - +
+ + + + \ No newline at end of file From d9ebcbd1f31836761732cbfb5b90d5aec17ee8bc Mon Sep 17 00:00:00 2001 From: jiyoung Date: Wed, 13 Dec 2023 22:11:02 +0900 Subject: [PATCH 4/8] =?UTF-8?q?week2:=20=EC=9E=A5=EB=B0=94=EA=B5=AC?= =?UTF-8?q?=EB=8B=88=201=EC=B0=A8=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/2week/app.js | 75 ++++++++++++++++++++---------------- src/2week/assets/css/app.css | 19 +++++++-- src/2week/index.html | 18 +++++++-- 3 files changed, 72 insertions(+), 40 deletions(-) diff --git a/src/2week/app.js b/src/2week/app.js index d87ea09..3a4e81b 100644 --- a/src/2week/app.js +++ b/src/2week/app.js @@ -15,15 +15,17 @@ function close_cart() { } function show_cart_list() { - cartList.innerHTML = shopping_cart.map( - (item) => ` -
- ${item.category} -

${item.name}

-

${item.price}

-
- ` - ); + cartList.innerHTML = shopping_cart + .map( + (item) => ` +
+ ${item.category} +

${item.name}

+

${formatNumberToCurrency(item.price)}

+
+ ` + ) + .join(''); } cartIcon.addEventListener('click', () => { @@ -42,7 +44,7 @@ function formatCurrencyToNumber(priceText) { } function formatNumberToCurrency(priceNum) { - return priceNum.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")+'원'; + return priceNum.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',') + '원'; } // items @@ -60,7 +62,6 @@ document.querySelectorAll('button').forEach((button) => function add_item_to_cart(item) { shopping_cart.push(item); - console.log(shopping_cart); calc_cart_total(); } @@ -76,43 +77,52 @@ function calc_cart_total() { update_shipping_icons(); } - function update_shipping_icons() { var buy_buttons = get_buy_buttons_dom(); for (var i = 0; i < buy_buttons.length; i++) { - var item = buy_buttons[i]; - console.log(item); - if (item.price + shopping_cart_total >= 20000) item.show_free_shipping_icon(); - else item.hide_free_shipping_icon(); + // 제품 item + shpping icon 기능 추가된 객체 + var btn = buy_buttons[i]; + const btn_item_price = formatCurrencyToNumber( + btn.parentNode.querySelector('.price').textContent + ); + if (btn_item_price + shopping_cart_total >= 20000) + btn.show_free_shipping_icon(); + else btn.hide_free_shipping_icon(); } } -// Q: shopping_cart를 복제하고, 무료 배송 아이콘을 보여주는 기능이 추가된 객체 배열. +// Q: 구매하기 버튼, function get_buy_buttons_dom() { var buttons = []; - const free_shipping_icon = document.querySelector('.free-shipping'); - for (var i = 0; i < shopping_cart.length; i++) { - var item = shopping_cart[i]; - item.show_free_shipping_icon = function () { - free_shipping_icon.classList.remove('hidden'); + const add_to_cart_btns = document.querySelectorAll('.add-to-cart'); + // shopping_cart를 도는 게 아니라 상품 전체를 돌아야 함 + for (var i = 0; i < add_to_cart_btns.length; i++) { + var btn = add_to_cart_btns[i]; + btn.show_free_shipping_icon = function () { + this.parentNode + .querySelector('.free-shipping-icon') + .classList.remove('hidden'); }; - item.hide_free_shipping_icon = function () { - free_shipping_icon.classList.add('hidden') + btn.hide_free_shipping_icon = function () { + this.parentNode + .querySelector('.free-shipping-icon') + .classList.add('hidden'); }; - buttons.push(item); + buttons.push(btn); } return buttons; } // tax를 더한다는 것을 제외하면 set_calc_total_dom 동작과 같음, calc+total 을 관리하는 돔으로 통합하는 건 ? -function update_tax_dom( cartTotal) { - const tax = calc_tax(cartTotal) +function update_tax_dom(cartTotal) { + const tax = calc_tax(cartTotal); set_total_price_dom(cartTotal + tax); } -function set_total_price_dom(totalNum){ - document.querySelector('.total-price').textContent = formatNumberToCurrency(totalNum); +function set_total_price_dom(totalNum) { + document.querySelector('.total-price').textContent = + formatNumberToCurrency(totalNum); } // function set_tax_dom(value) { @@ -123,7 +133,6 @@ function set_total_price_dom(totalNum){ // document.querySelector('.total-price').textContent = formatNumberToCurrency(total); // } - -function calc_tax(total){ - return total * 0.1 -} \ No newline at end of file +function calc_tax(total) { + return total * 0.1; +} diff --git a/src/2week/assets/css/app.css b/src/2week/assets/css/app.css index acc03b0..8361762 100644 --- a/src/2week/assets/css/app.css +++ b/src/2week/assets/css/app.css @@ -5,7 +5,7 @@ body { background-color: #f2eee9; - font: normal 13px/1.5 Georgia, Serif; + font: normal 13px/1.5 'sans-serif'; color: #333; } @@ -106,9 +106,14 @@ span { margin: 0 10px 0 0; } -.free-shipping{ - text-transform: uppercase; - color: red; +.free-shipping-icon { + color: #fff; + font-size: 13px; + background: #212529; + padding: 2px 6px; + border-radius: 8px; + margin-top: 10px; + float: left; } .category { @@ -151,11 +156,16 @@ p, } #cart-list { + display: flex; + flex-wrap: wrap; + gap: 8px; padding: 16px; } #cart-list .cart-item { + width: 100%; display: flex; + align-items: center; gap: 4px; background-color: #00585760; border-radius: 8px; @@ -174,5 +184,6 @@ p, } #cart-list .cart-item > .price { + width: 20%; font-weight: 700; } diff --git a/src/2week/index.html b/src/2week/index.html index 430d3ca..cf02e67 100644 --- a/src/2week/index.html +++ b/src/2week/index.html @@ -14,7 +14,7 @@

FECrash 카페

- /span> + 0원
@@ -33,7 +33,8 @@

C오늘의 커피

가격: 1,000원

- + +
item @@ -42,7 +43,8 @@

가격: 3,500원

- + +
item @@ -51,6 +53,7 @@

가격: 4,000원

+
@@ -60,6 +63,7 @@

가격: 3,900원

+
@@ -69,6 +73,7 @@

가격: 5,200원

+
@@ -78,6 +83,7 @@

가격: 4,800원

+
@@ -87,6 +93,7 @@

가격: 4,300원

+
@@ -96,6 +103,7 @@

가격: 5,500원

+
@@ -105,6 +113,7 @@

가격: 6,000원

+
@@ -114,6 +123,7 @@

가격: 7,000원

+
@@ -123,6 +133,7 @@

가격: 3,300원

+
@@ -132,6 +143,7 @@

가격: 7,200원

+
From 76cdd14a897ff4022722a079580eea62ca1744c7 Mon Sep 17 00:00:00 2001 From: ohtmm Date: Thu, 14 Dec 2023 17:31:31 +0900 Subject: [PATCH 5/8] =?UTF-8?q?2week:=201=EC=B0=A8=20=EB=A6=AC=ED=8C=A9?= =?UTF-8?q?=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/2week/app.js | 146 ++++++++++++++++++++++++++++------------------- 1 file changed, 88 insertions(+), 58 deletions(-) diff --git a/src/2week/app.js b/src/2week/app.js index 3a4e81b..4297117 100644 --- a/src/2week/app.js +++ b/src/2week/app.js @@ -1,22 +1,28 @@ + + var shopping_cart = []; var shopping_cart_total = 0; -// cart layer const cartLayer = document.getElementById('cart-layer'); const cartList = document.getElementById('cart-list'); const cartIcon = document.querySelector('.carts>.icons'); +const productList = document.querySelector('.items'); -function open_cart() { - cartLayer.style.display = 'block'; -} -function close_cart() { - cartLayer.style.display = 'none'; -} +// event_cart : oepn & close +cartIcon.addEventListener('click', () => { + show_dom(cartLayer); + set_cart_list_dom(shopping_cart, cartList); +}); + +cartLayer.addEventListener('click', (e) => { + if (e.target !== cartLayer) return; + hide_dom(cartLayer); +}); -function show_cart_list() { - cartList.innerHTML = shopping_cart - .map( + +function set_cart_list_dom(cartItems, cartContainer) { + cartContainer.innerHTML = cartItems.map( (item) => `
${item.category} @@ -28,56 +34,58 @@ function show_cart_list() { .join(''); } -cartIcon.addEventListener('click', () => { - open_cart(); - show_cart_list(); -}); -cartLayer.addEventListener('click', (e) => { - if (e.target !== cartLayer) return; - close_cart(); -}); - -function formatCurrencyToNumber(priceText) { - const regex = /,/g; - return parseFloat(priceText.replace(regex, '')); -} - -function formatNumberToCurrency(priceNum) { - return priceNum.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',') + '원'; -} - -// items -document.querySelectorAll('button').forEach((button) => +// event_products - add to cart +productList.querySelectorAll('.add-to-cart').forEach((button) => button.addEventListener('click', ({ target }) => { const name = target.parentNode.querySelector('.menu-name').textContent; const category = target.parentNode.querySelector('.category').textContent; - const price = formatCurrencyToNumber( - target.parentNode.querySelector('.price').textContent - ); + const price = formatCurrencyToNumber(target.parentNode.querySelector('.price').textContent); + + /* 전역 변수를 인자로 넘겨줬지만, 공유 객체이므로 카피해서 사용해야 하겠지? */ - add_item_to_cart({ name, category, price }); + // cart change + shopping_cart = add_item_to_cart({ name, category, price }, shopping_cart); + + // total change + shopping_cart_total = calc_cart_total(shopping_cart) + + // product change + update_shipping_icons(shopping_cart_total); }) ); -function add_item_to_cart(item) { - shopping_cart.push(item); - calc_cart_total(); +function add_item_to_cart(item, cart) { + return [...cart, item] } -// Q : 왜 cart_total 과 tax DOM 업데이트를 2번 해줘야 할까? -function calc_cart_total() { - shopping_cart_total = 0; - for (var i = 0; i < shopping_cart.length; i++) { - var item = shopping_cart[i]; - shopping_cart_total += item.price; +// header(total), main(product), cart(product) +function calc_cart_total(cart) { + const total = 0; + for (var i = 0; i < cart.length; i++) { + var item = cart[i]; + total += item.price; } - set_total_price_dom(shopping_cart_total); - update_tax_dom(shopping_cart_total); - update_shipping_icons(); + // Q : 왜 cart_total 과 tax DOM 업데이트를 2번 해줘야 할까? + set_total_price_dom(total); + update_tax_dom(total); + return total; +} + +//header(total) +function update_tax_dom(total) { + // tax를 더한다는 것을 제외하면 set_calc_total_dom 동작과 같음, calc+total 을 관리하는 돔으로 통합 + set_total_price_dom(total + calc_tax(total)); +} + +function set_total_price_dom(totalNum) { + document.querySelector('.total-price').textContent = + formatNumberToCurrency(totalNum); } -function update_shipping_icons() { + +// main(product) +function update_shipping_icons(total) { var buy_buttons = get_buy_buttons_dom(); for (var i = 0; i < buy_buttons.length; i++) { // 제품 item + shpping icon 기능 추가된 객체 @@ -85,16 +93,17 @@ function update_shipping_icons() { const btn_item_price = formatCurrencyToNumber( btn.parentNode.querySelector('.price').textContent ); - if (btn_item_price + shopping_cart_total >= 20000) + if (is_free_shipping(btn_item_price, total)) btn.show_free_shipping_icon(); else btn.hide_free_shipping_icon(); } } -// Q: 구매하기 버튼, +// main(product) function get_buy_buttons_dom() { var buttons = []; const add_to_cart_btns = document.querySelectorAll('.add-to-cart'); + // Q: 구매하기 버튼 // shopping_cart를 도는 게 아니라 상품 전체를 돌아야 함 for (var i = 0; i < add_to_cart_btns.length; i++) { var btn = add_to_cart_btns[i]; @@ -114,16 +123,9 @@ function get_buy_buttons_dom() { return buttons; } -// tax를 더한다는 것을 제외하면 set_calc_total_dom 동작과 같음, calc+total 을 관리하는 돔으로 통합하는 건 ? -function update_tax_dom(cartTotal) { - const tax = calc_tax(cartTotal); - set_total_price_dom(cartTotal + tax); -} -function set_total_price_dom(totalNum) { - document.querySelector('.total-price').textContent = - formatNumberToCurrency(totalNum); -} + + // function set_tax_dom(value) { // document.querySelector('.total-price').textContent = formatNumberToCurrency(value); @@ -133,6 +135,34 @@ function set_total_price_dom(totalNum) { // document.querySelector('.total-price').textContent = formatNumberToCurrency(total); // } + + +// 비즈니스 - 세금 function calc_tax(total) { return total * 0.1; } +// 비즈니스 - 배송 +function is_free_shipping( itemPrice, cartTotal){ + return itemPrice + cartTotal >= 20000 +} + +// utils ? - DOM +function show_dom(el) { + el.style.display = 'block'; +} + +// utils ? - DOM +function hide_dom() { + el.style.display = 'none'; +} + +// utils - format +function formatCurrencyToNumber(priceText) { + const regex = /,/g; + return parseFloat(priceText.replace(regex, '')); +} + +function formatNumberToCurrency(priceNum) { + return priceNum.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',') + '원'; +} + From 96e46c3b1f06483864a5717c8ac3b3f950fba56b Mon Sep 17 00:00:00 2001 From: ohtmm Date: Fri, 15 Dec 2023 12:00:55 +0900 Subject: [PATCH 6/8] =?UTF-8?q?2week:=202-1=EC=B0=A8=20=EB=A6=AC=ED=8C=A9?= =?UTF-8?q?=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/2week/app.js | 71 ++++++++++++++++++++++++----------------------- src/2week/cart.js | 33 ++++++++++++++++++++++ 2 files changed, 70 insertions(+), 34 deletions(-) create mode 100644 src/2week/cart.js diff --git a/src/2week/app.js b/src/2week/app.js index 4297117..49154fc 100644 --- a/src/2week/app.js +++ b/src/2week/app.js @@ -1,10 +1,10 @@ +import ShoppingCart from "./cart"; -var shopping_cart = []; -var shopping_cart_total = 0; +const {cartGetter: getCart, cartTotalGetter: getCartTotal, cartSetter: setCart} = ShoppingCart() + const cartLayer = document.getElementById('cart-layer'); -const cartList = document.getElementById('cart-list'); const cartIcon = document.querySelector('.carts>.icons'); const productList = document.querySelector('.items'); @@ -12,7 +12,7 @@ const productList = document.querySelector('.items'); // event_cart : oepn & close cartIcon.addEventListener('click', () => { show_dom(cartLayer); - set_cart_list_dom(shopping_cart, cartList); + set_cart_list_dom(); }); cartLayer.addEventListener('click', (e) => { @@ -21,8 +21,9 @@ cartLayer.addEventListener('click', (e) => { }); -function set_cart_list_dom(cartItems, cartContainer) { - cartContainer.innerHTML = cartItems.map( +function set_cart_list_dom() { + const cartList = document.getElementById('cart-list'); + cartList.innerHTML = getCart().map( (item) => `
${item.category} @@ -44,24 +45,31 @@ productList.querySelectorAll('.add-to-cart').forEach((button) => /* 전역 변수를 인자로 넘겨줬지만, 공유 객체이므로 카피해서 사용해야 하겠지? */ - // cart change - shopping_cart = add_item_to_cart({ name, category, price }, shopping_cart); + // cart change + // before : shopping_cart = add_item_to_cart({ name, category, price }, getCart()); + setCart('add', {name, category, price}) // total change - shopping_cart_total = calc_cart_total(shopping_cart) + // before : shopping_cart_total = calc_cart_total(shopping_cart) + // after :cart change 하면 자동으로 cart total update // product change - update_shipping_icons(shopping_cart_total); - }) + update_shipping_icons_dom(getCartTotal()); + set_total_price_dom(getCartTotal()); + + /* set_total_price_dom 에 통합 + update_tax_dom(getCartTotal()); + */ + }) ); -function add_item_to_cart(item, cart) { - return [...cart, item] -} +// function add_item_to_cart(item, cart) { + // return [...cart, item] +// } // header(total), main(product), cart(product) -function calc_cart_total(cart) { - const total = 0; +/* function calc_cart_total(cart) { + let total = 0; for (var i = 0; i < cart.length; i++) { var item = cart[i]; total += item.price; @@ -70,26 +78,25 @@ function calc_cart_total(cart) { set_total_price_dom(total); update_tax_dom(total); return total; -} +}*/ -//header(total) +/* header(total) function update_tax_dom(total) { // tax를 더한다는 것을 제외하면 set_calc_total_dom 동작과 같음, calc+total 을 관리하는 돔으로 통합 set_total_price_dom(total + calc_tax(total)); } +*/ -function set_total_price_dom(totalNum) { +function set_total_price_dom(total) { document.querySelector('.total-price').textContent = - formatNumberToCurrency(totalNum); + formatNumberToCurrency(total)+calc_tax(total); } // main(product) -function update_shipping_icons(total) { - var buy_buttons = get_buy_buttons_dom(); - for (var i = 0; i < buy_buttons.length; i++) { - // 제품 item + shpping icon 기능 추가된 객체 - var btn = buy_buttons[i]; +function update_shipping_icons_dom(total) { + const buy_buttons = get_buy_buttons_dom(); + buy_buttons.forEach((btn)=>{ const btn_item_price = formatCurrencyToNumber( btn.parentNode.querySelector('.price').textContent ); @@ -97,16 +104,16 @@ function update_shipping_icons(total) { btn.show_free_shipping_icon(); else btn.hide_free_shipping_icon(); } + ) + } // main(product) function get_buy_buttons_dom() { - var buttons = []; const add_to_cart_btns = document.querySelectorAll('.add-to-cart'); // Q: 구매하기 버튼 // shopping_cart를 도는 게 아니라 상품 전체를 돌아야 함 - for (var i = 0; i < add_to_cart_btns.length; i++) { - var btn = add_to_cart_btns[i]; + return add_to_cart_btns.map(btn => { btn.show_free_shipping_icon = function () { this.parentNode .querySelector('.free-shipping-icon') @@ -117,11 +124,7 @@ function get_buy_buttons_dom() { .querySelector('.free-shipping-icon') .classList.add('hidden'); }; - buttons.push(btn); - } - - return buttons; -} + })} @@ -152,7 +155,7 @@ function show_dom(el) { } // utils ? - DOM -function hide_dom() { +function hide_dom(el) { el.style.display = 'none'; } diff --git a/src/2week/cart.js b/src/2week/cart.js new file mode 100644 index 0000000..5ad25ee --- /dev/null +++ b/src/2week/cart.js @@ -0,0 +1,33 @@ +const ShoppingCart = () => { + const shopping_cart = []; + const shopping_cart_total = shopping_cart.reduce((item,acc)=> acc + item.price, 0); + + + const cartGetter = () => [...shopping_cart] + + const cartTotalGetter = () => shopping_cart_total + + const cartSetter = (action, item) => { + switch(action){ + case 'add' : + shopping_cart = [...shopping_cart, item] + break; + case 'update' : + + break; + case 'delete': + + break; + default : + throw new Error('Action must be one of "add", "update", or "delete"') + } + } + + + return { + cartGetter, + cartTotalGetter, + cartSetter, + }} + + export default ShoppingCart; \ No newline at end of file From 64060707e35dc9c3842dc927f22d788620b00dde Mon Sep 17 00:00:00 2001 From: ohtmm Date: Mon, 18 Dec 2023 17:26:29 +0900 Subject: [PATCH 7/8] =?UTF-8?q?2week:=202-1=20=EC=98=A4=EB=A5=98=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/2week/app.js | 111 ++++++++++++++++--------------------------- src/2week/cart.js | 6 +-- src/2week/index.html | 2 +- 3 files changed, 44 insertions(+), 75 deletions(-) diff --git a/src/2week/app.js b/src/2week/app.js index 49154fc..3c7730d 100644 --- a/src/2week/app.js +++ b/src/2week/app.js @@ -1,4 +1,4 @@ -import ShoppingCart from "./cart"; +import ShoppingCart from "./cart.js"; const {cartGetter: getCart, cartTotalGetter: getCartTotal, cartSetter: setCart} = ShoppingCart() @@ -9,7 +9,6 @@ const cartIcon = document.querySelector('.carts>.icons'); const productList = document.querySelector('.items'); -// event_cart : oepn & close cartIcon.addEventListener('click', () => { show_dom(cartLayer); set_cart_list_dom(); @@ -35,111 +34,75 @@ function set_cart_list_dom() { .join(''); } +function get_dom_text (className, target = document){ +return target.querySelector(`${className}`).textContent; +} -// event_products - add to cart -productList.querySelectorAll('.add-to-cart').forEach((button) => - button.addEventListener('click', ({ target }) => { - const name = target.parentNode.querySelector('.menu-name').textContent; - const category = target.parentNode.querySelector('.category').textContent; - const price = formatCurrencyToNumber(target.parentNode.querySelector('.price').textContent); +function get_dom_num (className, target = document){ + return formatToNumber(target.querySelector(`${className}`).textContent); +} - /* 전역 변수를 인자로 넘겨줬지만, 공유 객체이므로 카피해서 사용해야 하겠지? */ +const ITEM_STRING =['name', 'category']; +const ITEM_NUMBER = ['price'] + +function make_cart_item(keys,target = document){ + const cartItem = {} + keys.forEach(key => { + if( ITEM_STRING.includes(key)){ + cartItem[key] = get_dom_text(key,target) + }else{ + cartItem[key] = get_dom_num(key, target) + } + }) + return cartItem; +} - // cart change - // before : shopping_cart = add_item_to_cart({ name, category, price }, getCart()); - setCart('add', {name, category, price}) - // total change - // before : shopping_cart_total = calc_cart_total(shopping_cart) - // after :cart change 하면 자동으로 cart total update +productList.querySelectorAll('.add-to-cart').forEach((button) => + button.addEventListener('click', ({ target }) => { + const name = get_dom_text('name', target.parentNode); + const category = get_dom_text('category', target.parentNode); + const price = get_dom_num('price', target.parentNode); - // product change + setCart('add', {name, category, price}) update_shipping_icons_dom(getCartTotal()); set_total_price_dom(getCartTotal()); - - /* set_total_price_dom 에 통합 - update_tax_dom(getCartTotal()); - */ }) ); -// function add_item_to_cart(item, cart) { - // return [...cart, item] -// } - -// header(total), main(product), cart(product) -/* function calc_cart_total(cart) { - let total = 0; - for (var i = 0; i < cart.length; i++) { - var item = cart[i]; - total += item.price; - } - // Q : 왜 cart_total 과 tax DOM 업데이트를 2번 해줘야 할까? - set_total_price_dom(total); - update_tax_dom(total); - return total; -}*/ - -/* header(total) -function update_tax_dom(total) { - // tax를 더한다는 것을 제외하면 set_calc_total_dom 동작과 같음, calc+total 을 관리하는 돔으로 통합 - set_total_price_dom(total + calc_tax(total)); -} -*/ - function set_total_price_dom(total) { document.querySelector('.total-price').textContent = - formatNumberToCurrency(total)+calc_tax(total); + formatNumberToCurrency(total+calc_tax(total)); } - -// main(product) function update_shipping_icons_dom(total) { const buy_buttons = get_buy_buttons_dom(); buy_buttons.forEach((btn)=>{ - const btn_item_price = formatCurrencyToNumber( - btn.parentNode.querySelector('.price').textContent - ); + const btn_item_price = get_dom_num('price',btn.parentNode) if (is_free_shipping(btn_item_price, total)) btn.show_free_shipping_icon(); else btn.hide_free_shipping_icon(); } - ) - + ) } -// main(product) function get_buy_buttons_dom() { - const add_to_cart_btns = document.querySelectorAll('.add-to-cart'); - // Q: 구매하기 버튼 - // shopping_cart를 도는 게 아니라 상품 전체를 돌아야 함 + const add_to_cart_btns = Array.from(document.querySelectorAll('.add-to-cart')); return add_to_cart_btns.map(btn => { btn.show_free_shipping_icon = function () { this.parentNode .querySelector('.free-shipping-icon') .classList.remove('hidden'); - }; + }; btn.hide_free_shipping_icon = function () { this.parentNode .querySelector('.free-shipping-icon') .classList.add('hidden'); - }; + }; + return btn })} - - - -// function set_tax_dom(value) { -// document.querySelector('.total-price').textContent = formatNumberToCurrency(value); -// } - -// function set_cart_total_dom(total) { -// document.querySelector('.total-price').textContent = formatNumberToCurrency(total); -// } - - - // 비즈니스 - 세금 function calc_tax(total) { return total * 0.1; @@ -160,11 +123,17 @@ function hide_dom(el) { } // utils - format +function formatToNumber(text){ + return parseFloat(text.replace(/[^\d]/g,'')); +} +/* function formatCurrencyToNumber(priceText) { const regex = /,/g; return parseFloat(priceText.replace(regex, '')); } +*/ + function formatNumberToCurrency(priceNum) { return priceNum.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',') + '원'; } diff --git a/src/2week/cart.js b/src/2week/cart.js index 5ad25ee..be25e61 100644 --- a/src/2week/cart.js +++ b/src/2week/cart.js @@ -1,16 +1,16 @@ const ShoppingCart = () => { - const shopping_cart = []; - const shopping_cart_total = shopping_cart.reduce((item,acc)=> acc + item.price, 0); + let shopping_cart = []; const cartGetter = () => [...shopping_cart] - const cartTotalGetter = () => shopping_cart_total + const cartTotalGetter = () => shopping_cart.reduce((acc,item)=> acc + item.price, 0); const cartSetter = (action, item) => { switch(action){ case 'add' : shopping_cart = [...shopping_cart, item] + console.log(shopping_cart) break; case 'update' : diff --git a/src/2week/index.html b/src/2week/index.html index cf02e67..6476c9a 100644 --- a/src/2week/index.html +++ b/src/2week/index.html @@ -148,7 +148,7 @@

- + \ No newline at end of file From 7da139d956f873e977540bc65322ef965aa5522a Mon Sep 17 00:00:00 2001 From: jiyoung Date: Mon, 18 Dec 2023 20:17:00 +0900 Subject: [PATCH 8/8] =?UTF-8?q?week2:=202-2=EC=B0=A8=20=EB=A6=AC=ED=8C=A9?= =?UTF-8?q?=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/2week/app.js | 165 ++++++++++++++++++++++++---------------------- src/2week/cart.js | 51 +++++++------- 2 files changed, 112 insertions(+), 104 deletions(-) diff --git a/src/2week/app.js b/src/2week/app.js index 3c7730d..a410af0 100644 --- a/src/2week/app.js +++ b/src/2week/app.js @@ -1,14 +1,15 @@ -import ShoppingCart from "./cart.js"; - - -const {cartGetter: getCart, cartTotalGetter: getCartTotal, cartSetter: setCart} = ShoppingCart() +import ShoppingCart from './cart.js'; +const { + cartGetter: getCart, + cartTotalGetter: getCartTotal, + cartSetter: setCart, +} = ShoppingCart(); const cartLayer = document.getElementById('cart-layer'); const cartIcon = document.querySelector('.carts>.icons'); const productList = document.querySelector('.items'); - cartIcon.addEventListener('click', () => { show_dom(cartLayer); set_cart_list_dom(); @@ -19,14 +20,73 @@ cartLayer.addEventListener('click', (e) => { hide_dom(cartLayer); }); +productList.querySelectorAll('.add-to-cart').forEach((button) => + button.addEventListener('click', ({ target }) => { + setCart('add', makeCartItem(target.parentNode)); + update_shipping_icons_dom(getCartTotal()); + set_total_price_dom(getCartTotal()); + }) +); + +// action - dom : get_dom_value 호출 +function makeCartItem(targetProduct = document) { + const PRODUCT_KEYS = [ + { + type: 'string', + className: 'category', + }, + { + type: 'number', + className: 'price', + }, + { + type: 'string', + className: 'menu-name', + }, + ]; + + const cartItem = {}; + PRODUCT_KEYS.forEach((key) => { + cartItem[key.className] = get_dom_value( + key.className, + key.type, + targetProduct + ); + }); + return cartItem; +} +// action - dom : get_buy_buttons_dom 호출 +function update_shipping_icons_dom(total) { + const buy_buttons = get_buy_buttons_dom(); + buy_buttons.forEach((btn) => { + const btn_item_price = get_dom_value('price', 'number', btn.parentNode); + if (is_free_shipping(btn_item_price, total)) btn.show_free_shipping_icon(); + else btn.hide_free_shipping_icon(); + }); +} + +// action - dom [dynamicSelector] +function get_dom_value(className, valueType, target = document) { + const el = target.querySelector(`.${className}`); + if (!el) return null; + + if (valueType === 'string') { + return el.textContent; + } else { + return formatToNumber(el.textContent); + } +} + +// action - dom 'cart-list' function set_cart_list_dom() { const cartList = document.getElementById('cart-list'); - cartList.innerHTML = getCart().map( + cartList.innerHTML = getCart() + .map( (item) => `
${item.category} -

${item.name}

+

${item['menu-name']}

${formatNumberToCurrency(item.price)}

` @@ -34,82 +94,40 @@ function set_cart_list_dom() { .join(''); } -function get_dom_text (className, target = document){ -return target.querySelector(`${className}`).textContent; -} - -function get_dom_num (className, target = document){ - return formatToNumber(target.querySelector(`${className}`).textContent); -} - -const ITEM_STRING =['name', 'category']; -const ITEM_NUMBER = ['price'] - -function make_cart_item(keys,target = document){ - const cartItem = {} - keys.forEach(key => { - if( ITEM_STRING.includes(key)){ - cartItem[key] = get_dom_text(key,target) - }else{ - cartItem[key] = get_dom_num(key, target) - } - }) - return cartItem; -} - - -productList.querySelectorAll('.add-to-cart').forEach((button) => - button.addEventListener('click', ({ target }) => { - const name = get_dom_text('name', target.parentNode); - const category = get_dom_text('category', target.parentNode); - const price = get_dom_num('price', target.parentNode); - - setCart('add', {name, category, price}) - update_shipping_icons_dom(getCartTotal()); - set_total_price_dom(getCartTotal()); - }) -); - +// action - dom 'total-price' function set_total_price_dom(total) { - document.querySelector('.total-price').textContent = - formatNumberToCurrency(total+calc_tax(total)); -} - -function update_shipping_icons_dom(total) { - const buy_buttons = get_buy_buttons_dom(); - buy_buttons.forEach((btn)=>{ - const btn_item_price = get_dom_num('price',btn.parentNode) - if (is_free_shipping(btn_item_price, total)) - btn.show_free_shipping_icon(); - else btn.hide_free_shipping_icon(); - } - ) + document.querySelector('.total-price').textContent = formatNumberToCurrency( + total + calc_tax(total) + ); } +// action - dom 'add-to-cart' function get_buy_buttons_dom() { - const add_to_cart_btns = Array.from(document.querySelectorAll('.add-to-cart')); - return add_to_cart_btns.map(btn => { + const add_to_cart_btns = Array.from( + document.querySelectorAll('.add-to-cart') + ); + return add_to_cart_btns.map((btn) => { btn.show_free_shipping_icon = function () { this.parentNode .querySelector('.free-shipping-icon') .classList.remove('hidden'); - }; + }; btn.hide_free_shipping_icon = function () { this.parentNode .querySelector('.free-shipping-icon') .classList.add('hidden'); - }; - return btn - })} - + }; + return btn; + }); +} -// 비즈니스 - 세금 +// 비즈니스 - 세금 function calc_tax(total) { return total * 0.1; } -// 비즈니스 - 배송 -function is_free_shipping( itemPrice, cartTotal){ - return itemPrice + cartTotal >= 20000 +// 비즈니스 - 배송 +function is_free_shipping(itemPrice, cartTotal) { + return itemPrice + cartTotal >= 20000; } // utils ? - DOM @@ -123,18 +141,11 @@ function hide_dom(el) { } // utils - format -function formatToNumber(text){ - return parseFloat(text.replace(/[^\d]/g,'')); -} -/* -function formatCurrencyToNumber(priceText) { - const regex = /,/g; - return parseFloat(priceText.replace(regex, '')); +function formatToNumber(text) { + return parseFloat(text.replace(/[^\d]/g, '')); } -*/ - +// utils - format function formatNumberToCurrency(priceNum) { return priceNum.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',') + '원'; } - diff --git a/src/2week/cart.js b/src/2week/cart.js index be25e61..d8a615b 100644 --- a/src/2week/cart.js +++ b/src/2week/cart.js @@ -1,33 +1,30 @@ const ShoppingCart = () => { - let shopping_cart = []; + let shopping_cart = []; + const cartGetter = () => [...shopping_cart]; - const cartGetter = () => [...shopping_cart] - - const cartTotalGetter = () => shopping_cart.reduce((acc,item)=> acc + item.price, 0); - - const cartSetter = (action, item) => { - switch(action){ - case 'add' : - shopping_cart = [...shopping_cart, item] - console.log(shopping_cart) - break; - case 'update' : - - break; - case 'delete': + const cartTotalGetter = () => + shopping_cart.reduce((acc, item) => acc + item.price, 0); - break; - default : - throw new Error('Action must be one of "add", "update", or "delete"') - } - } + const cartSetter = (action, item) => { + switch (action) { + case 'add': + shopping_cart = [...shopping_cart, item]; + break; + case 'update': + break; + case 'delete': + break; + default: + throw new Error('Action must be one of "add", "update", or "delete"'); + } + }; + return { + cartGetter, + cartTotalGetter, + cartSetter, + }; +}; - return { - cartGetter, - cartTotalGetter, - cartSetter, - }} - - export default ShoppingCart; \ No newline at end of file +export default ShoppingCart;