From b95cf76fc0dcb8f86f18afedaf8c1a0b0237c71c Mon Sep 17 00:00:00 2001 From: SUMMERLOVE7 Date: Wed, 22 Feb 2023 19:07:32 +0900 Subject: [PATCH] =?UTF-8?q?feat(FE):=20swipe=20=EA=B8=B0=EB=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/apis/card.js | 12 ++++ client/src/components/main/cardDetail.js | 3 +- client/src/pages/MainPage.js | 87 ++++++++++++++++++++---- client/src/styles/main.scss | 71 ++++++++++++++++++- 4 files changed, 158 insertions(+), 15 deletions(-) diff --git a/client/src/apis/card.js b/client/src/apis/card.js index 5022b07..9b0a14b 100644 --- a/client/src/apis/card.js +++ b/client/src/apis/card.js @@ -29,3 +29,15 @@ export const getUsedCard = async () => { console.error(e); } }; + +export const deleteACard = async (gifticonId) => { + if (typeof gifticonId === 'string') parseInt(gifticonId, 10); + + try { + const response = await client.delete(`gifticon`, { data: { gifticonId } }); + + return response.data; + } catch (e) { + console.error(e); + } +}; diff --git a/client/src/components/main/cardDetail.js b/client/src/components/main/cardDetail.js index 6590975..01a7d5f 100644 --- a/client/src/components/main/cardDetail.js +++ b/client/src/components/main/cardDetail.js @@ -1,7 +1,7 @@ import { SERVER_URL } from '@/constants/constant.js'; const cardDetail = (props) => (idx) => { - const { image, thumbnail, brandName, itemName, expiresAt, price, barcode } = props; + const { image, thumbnail, brandName, itemName, expiresAt, price, barcode, id } = props; const DOTS_ICON_URL = `${SERVER_URL.IMG}icon/dots.svg`; const cardDetailTemplate = ` @@ -11,6 +11,7 @@ const cardDetail = (props) => (idx) => {
more-dots-button +
${id}
${expiresAt}
${brandName}
${itemName}
diff --git a/client/src/pages/MainPage.js b/client/src/pages/MainPage.js index a111a8b..30ff816 100644 --- a/client/src/pages/MainPage.js +++ b/client/src/pages/MainPage.js @@ -5,7 +5,7 @@ import { dropdownMenu, header, notification } from '@/components/common'; import { IO, $, slider } from '@/utils'; import { _ } from '@/utils/customFx'; import { navigate } from '@/core/router'; -import { getCardList } from '@/apis/card'; +import { getCardList, deleteACard } from '@/apis/card'; const ONE_CARD_ICON_URL = `${SERVER_URL.IMG}icon/image-icon.svg`; const LIST_ICON_URL = `${SERVER_URL.IMG}icon/list-icon.svg`; @@ -15,6 +15,7 @@ let touchStartX = 0; let touchEndX = 0; let isSwipping = false; let cardDatas = []; +let sortOpt = ''; const setCardDatas = (cardData) => (cardDatas = [...cardData]); const sortOption = { 0: '마감순', 1: '등록순', 2: '금액순' }; @@ -106,11 +107,38 @@ const toggleDropdown = () => { dropDownTarget.addEventListener('click', (e) => handleSortClick(e, dropdownSection)); }; -const makeGrayScale = (target) => target.closest('.one-card-section').classList.add('gray'); +// const makeGrayScale = (target) => target.closest('.one-card-section').classList.add('gray'); +const makeGrayScale = (target) => { + const list = target.closest('.card-lists'); + list.querySelector('.one-card-section').classList.add('gray'); +}; const makeUsedState = (targets) => targets.forEach((button) => button.addEventListener('click', (e) => makeGrayScale(e.target))); +const swipeButtonTpl = ` +
+
+ 사용완료 +
+
+ 삭제하기 +
+
+ `; + +// prettier-ignore +const renderButton = (target) => + _.go( + swipeButtonTpl, + $.el, + $.append(target)); + +const renderButtons = (targets) => { + if ($.qs('.card-actions-section')) return; + targets.forEach((list) => renderButton(list)); +}; + const listEvent = (targets) => { targets.forEach((card) => { card.addEventListener('touchstart', handleTouchStart); @@ -121,32 +149,65 @@ const listEvent = (targets) => { const handleTouchStart = (e) => (touchStartX = e.touches[0].clientX); -const handleTouchMove = (e) => (touchEndX = e.touches[0].clientX); +const handleTouchEnd = () => { + touchStartX = 0; +}; + +// const handleTouchMove = (e) => (touchEndX = e.touches[0].clientX); -const handleTouchEnd = (e) => { +// const handleTouchEnd = (e) => { +const handleTouchMove = (e) => { const touchDeltaX = touchEndX - touchStartX; const card = e.currentTarget; const isSwippingRight = card.classList.contains('swiped-right'); const isSwippingLeft = card.classList.contains('swiped-left'); - if (touchDeltaX > 20 && !isSwipping && !isSwippingLeft) { - isSwipping = true; - card.classList.add('swiped-right'); - } else if (touchDeltaX < -20 && !isSwipping && !isSwippingRight) { + console.log(touchStartX, e.touches[0].clientX); + + if (touchStartX - e.touches[0].clientX > 7 && !isSwipping && !isSwippingRight) { isSwipping = true; card.classList.add('swiped-left'); - } else if (touchDeltaX < -20 && isSwipping && !isSwippingLeft) { - card.classList.remove('swiped-right'); - isSwipping = false; - } else if (touchDeltaX > 20 && isSwipping && !isSwippingRight) { + } else if (e.touches[0].clientX - touchStartX > -7 && !isSwipping && !isSwippingLeft) { + isSwipping = true; + card.classList.add('swiped-right'); + } else if (e.touches[0].clientX - touchStartX > -7 && isSwipping && !isSwippingRight) { card.classList.remove('swiped-left'); isSwipping = false; + } else if (touchStartX - e.touches[0].clientX > 7 && isSwipping && !isSwippingLeft) { + card.classList.remove('swiped-right'); + isSwipping = false; } }; +const deleteCard = async (e) => { + const list = e.target.closest('.card-lists'); + const id = list.querySelector('.card-id').innerText; + console.log(id); + await deleteACard(id); + navigateMain('/card'); +}; + +const deleteCardEvent = (targets) => + targets.forEach((button) => button.addEventListener('click', (e) => deleteCard(e))); + const switchLayout = ({ target }) => { if (target.className === 'one-card-button') $.qs('.cards-section').classList.remove('list'); - else $.qs('.cards-section').classList.add('list'); + else { + $.qs('.cards-section').classList.add('list'); + + if ($.qs('.cards-section').classList.contains('list')) { + const cardLists = $.qsa('.card-lists'); + listEvent(cardLists); + renderButtons(cardLists); + + const usedButtons = $.qsa('.card-used-button'); + console.log(usedButtons); + makeUsedState(usedButtons); + + const deleteButtons = $.qsa('.card-delete-button'); + deleteCardEvent(deleteButtons); + } + } }; const dateComparison = () => diff --git a/client/src/styles/main.scss b/client/src/styles/main.scss index 2520d5c..208e093 100644 --- a/client/src/styles/main.scss +++ b/client/src/styles/main.scss @@ -155,7 +155,6 @@ perspective: 800px; &.is-flipped { - height: 100%; .one-card-section { transform: rotateY(-180deg); } @@ -238,6 +237,10 @@ font-size: 1rem; color: $gray600; } + + .card-id { + display: none; + } } .mark-used-button { @@ -264,6 +267,7 @@ scrollbar-width: none; transition: 0s; transform: translateX(0px) !important; + touch-action: none; &::-webkit-scrollbar { display: none; @@ -367,6 +371,10 @@ display: flex; } + .card-id { + display: none; + } + .date-of-use { font-size: 0.5rem; color: #757575; @@ -388,6 +396,67 @@ margin: 0; } } + + &.swiped-right { + transform: translateX(64px); + // transform: translateX(60px); + transition: transform 0.5s; + } + + &.swiped-left { + transform: translateX(-64px); + // transform: translateX(-60px); + transition: transform 0.5s; + } + + &.gray { + filter: grayscale(1); + } + + .card-actions-section { + position: absolute; + top: 0; + left: 0; + width: calc(90vw - 2.5rem - 2px + 128px); + height: 100%; + display: flex; + justify-content: space-between; + align-items: center; + transition: transform 0.2s ease-in-out; + margin-left: -64px; + + .card-used-button { + background-color: $primary-color; + width: 4rem; + height: 100%; + color: black; + font-size: 1rem; + cursor: pointer; + transition: transform 0.2s ease-in-out; + text-align: center; + display: flex; + align-items: center; + justify-content: center; + color: $white-color; + border-radius: 0.5rem; + text-align: center; + } + + .card-delete-button { + background-color: $pink-color; + width: 4rem; + height: 100%; + font-size: 1rem; + cursor: pointer; + transition: transform 0.2s ease-in-out; + text-align: center; + display: flex; + align-items: center; + justify-content: center; + border-radius: 0.5rem; + color: $white-color; + } + } } .card-lists:last-of-type {