From f6c2f9edad684942235a651ad1d4c53ff1d3c7ee Mon Sep 17 00:00:00 2001 From: Yerin Date: Mon, 6 May 2024 17:42:59 +0900 Subject: [PATCH 1/4] =?UTF-8?q?refactor:=20=ED=95=A8=EC=88=98=EB=AA=85=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- css/common.css | 9 +++++++++ img/detail/star-fill.svg | 2 +- img/detail/star-half.svg | 2 +- js/review/index.js | 10 ++++++---- js/review/reviewForm/isValidReviewValues.js | 20 +++++++++++++++++-- ...ngClickHandler.js => starRatingHandler.js} | 4 ++-- .../{addReviewToLocalStorage.js => utils.js} | 5 +---- ...SubmitHandler.js => writeReviewHandler.js} | 13 ++++++------ js/review/reviewList/renderMovieReviews.js | 12 +++++++---- js/review/utils.js | 9 +++++++-- review.html | 6 +++--- 11 files changed, 62 insertions(+), 30 deletions(-) rename js/review/reviewForm/{reviewRatingClickHandler.js => starRatingHandler.js} (88%) rename js/review/reviewForm/{addReviewToLocalStorage.js => utils.js} (85%) rename js/review/reviewForm/{reviewFormSubmitHandler.js => writeReviewHandler.js} (65%) diff --git a/css/common.css b/css/common.css index d469380..fc2c7b2 100644 --- a/css/common.css +++ b/css/common.css @@ -1,3 +1,12 @@ body { background-color: #1b1b1b; +} + +.blind { + position: absolute !important; + height: 1px; + width: 1px; + overflow: hidden; + clip: rect(1px 1px 1px 1px); + clip: rect(1px, 1px, 1px, 1px); } \ No newline at end of file diff --git a/img/detail/star-fill.svg b/img/detail/star-fill.svg index 581deb8..3e6d5f4 100644 --- a/img/detail/star-fill.svg +++ b/img/detail/star-fill.svg @@ -1,3 +1,3 @@ -
이 영화에 대한 감상평이 없어요
지금 작성하시면, 첫번째로 남기실 수 있어요 😆
`; @@ -8,14 +8,14 @@ const renderMovieReviews = (reviews = []) => { let html = ''; - reviews.forEach((result) => { - html += getReviewHtml(result); + reviews.forEach((result, index) => { + html += getReviewHtml(result, index); }); $wrap.innerHTML = ``; } -const getReviewHtml = (result) => { +const getReviewHtml = (result, index) => { return `
  • @@ -27,6 +27,10 @@ const getReviewHtml = (result) => {

    ${result.comment}

    +
      +
    • +
    • +
  • `; diff --git a/js/review/utils.js b/js/review/utils.js index 5637dac..a3017dd 100644 --- a/js/review/utils.js +++ b/js/review/utils.js @@ -3,7 +3,7 @@ import {getLocalStorage, setLocalStorage} from "../utils/localStorage.js"; const LOCALSTORAGE_COMMENTS = 'comments'; const LOCALSTORAGE_USER_INFO = 'user-information'; -const TEST_VALUE = '123'; +const TEST_VALUE = '1234'; console.log('@@ TODO: 테스트 값 꼭 삭제하기'); export const getMovieIdFromURL = () => getUrlParamValue('movie_id') || TEST_VALUE; @@ -26,4 +26,9 @@ export const getUser = () => JSON.parse(getLocalStorage(LOCALSTORAGE_USER_INFO) export const getUserInformation = () => { const { username, password, imageUrl } = getUser(); return { username, password, imageUrl } -} \ No newline at end of file +} + +export const notifyAndReload = (message) => { + window.alert(message); + window.location.reload(); +}; \ No newline at end of file diff --git a/review.html b/review.html index 4b06dde..6035ea4 100644 --- a/review.html +++ b/review.html @@ -14,9 +14,9 @@ -
    +

    감상평

    -
    +

    평가하기

    @@ -44,6 +44,6 @@

    평가하기

    평가하기 -
    +
    \ No newline at end of file From c7ae431d4b6d90d9d7f437d55b15f35da08ce12c Mon Sep 17 00:00:00 2001 From: Yerin Date: Mon, 6 May 2024 17:51:54 +0900 Subject: [PATCH 2/4] =?UTF-8?q?feat:=20=EB=8C=93=EA=B8=80=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- css/review.css | 142 ++++++++++++++++++-- js/review/reviewForm/deleteReviewHandler.js | 33 +++++ js/review/reviewForm/useDeleteModal.js | 32 +++++ js/review/reviewForm/utils.js | 12 ++ 4 files changed, 206 insertions(+), 13 deletions(-) create mode 100644 js/review/reviewForm/deleteReviewHandler.js create mode 100644 js/review/reviewForm/useDeleteModal.js diff --git a/css/review.css b/css/review.css index a97b5bb..d9dad33 100644 --- a/css/review.css +++ b/css/review.css @@ -1,4 +1,4 @@ -.review-wrap { +#reviewContainer { --title-color0: #ffffff; --title-color1: #dee1e9; --title-color2: #84868d; @@ -11,6 +11,8 @@ font-size: 15px; gap: 16px; margin-bottom: 30px; + position: relative; + z-index: 0; } #reviews .name { @@ -90,7 +92,7 @@ outline: none; } -.review-wrap { +#reviewContainer { max-width: 1240px; margin: 0 auto; padding: 3%; @@ -159,22 +161,136 @@ flex-shrink: 0; } -#writeReviewForm .text-input { - height: 38px; - background: none; - border: none; - color: var(--title-color1); +#reviewList .empty-review { + color: var(--title-color2); + padding: 0 0 80px; font-size: 15px; + line-height: 1.6; + text-align: center; +} + +.comment-util { + position: absolute; + top: 6px; + right: 0; + display: flex; + gap: 5px; + font-size: 12px; + z-index: 1; +} + +#reviews li { + position: relative; +} + +.comment-util li + li:before { + position: absolute; + top: 4px; + left: -3px; + content: ""; + width: 1px; + height: 10px; + background-color: #2f2f2f; +} + +.comment-util button { + color: inherit; + font-size: inherit; + padding: 2px 4px; +} + +#reviewContainer #popup { + position: fixed; + top: 0; + left: 0; + z-index: 100; + width: 100%; + height: 100%; + background: rgba(0, 0, 0, 50%); + display: flex; + align-items: center; + justify-content: center; +} + +#reviewContainer #modalForm { + background: var(--title-color0); + border-radius: 12px; + padding: 36px 22px 30px; + width: 350px; + position: relative; +} + +#reviewContainer #popup strong { + display: block; + margin-bottom: 20px; + font-size: 17px; + font-weight: 700; +} + +#reviewContainer #popup .modal-button { + background: #000000; + width: 100%; + color: var(--title-color0); + height: 46px; + font-size: 15px; + border-radius: 4px; + margin-top: 10px; + display: block; + font-weight: 500; +} + +button.close-button { + width: 35px; + height: 35px; + background: #eeeeee; + border-radius: 50%; + position: absolute; + top: 12px; + right: 12px; + cursor: pointer; +} + +button.close-button:before { + width: 14px; + height: 2px; + background: #555555; + border-radius: 2px; + position: absolute; + content: ''; + top: 50%; + margin-top: -1px; + margin-left: -7px; + transform: rotate(45deg); +} + +button.close-button:after { + width: 14px; + height: 2px; + background: #555555; + border-radius: 2px; + position: absolute; + content: ''; + top: 50%; + margin-top: -1px; + margin-left: -7px; + transform: rotate(-45deg); +} + + +.text-input { + height: 45px; + background: none; + color: #000000; border-radius: 4px; padding: 10px; flex-grow: 2; outline: none; + width: 100%; + border: 1px solid var(--title-color1); + font-size: 15px; } -#reviewContainer .empty-review { - color: var(--title-color2); - padding: 0 0 80px; - font-size: 15px; - line-height: 1.6; - text-align: center; +.text-input:not(:placeholder-shown) { + font: small-caption; + font-size: 34px; } \ No newline at end of file diff --git a/js/review/reviewForm/deleteReviewHandler.js b/js/review/reviewForm/deleteReviewHandler.js new file mode 100644 index 0000000..cb09bde --- /dev/null +++ b/js/review/reviewForm/deleteReviewHandler.js @@ -0,0 +1,33 @@ +import {deleteReviewToLocalStorage} from "./utils.js"; +import {isValidPassword} from "./isValidReviewValues.js"; +import {notifyAndReload} from "../utils.js"; +import useDeleteModal from "./useDeleteModal.js"; + +const deleteReviewHandler = () => { + const handleButtonClick = (event) => { + const index = parseInt(event.target.closest('.comment-util').dataset.index); + + const modal = useDeleteModal({ + name: 'popup', + onSubmit: () => onSubmit({passwordInput, index}) + }); + + const passwordInput = modal.querySelector('.text-input[type=password]'); + passwordInput.focus(); + + document.getElementById('reviewContainer').appendChild(modal); + }; + + document.querySelectorAll('.comment-util .delete-btn') + .forEach(btn => btn.addEventListener('click', handleButtonClick)); +}; + +const onSubmit = ({passwordInput, index}) => { + const isValid = isValidPassword(passwordInput.value); + if (!isValid) return; + + deleteReviewToLocalStorage(index); + notifyAndReload('삭제가 완료되었어요'); +}; + +export default deleteReviewHandler; \ No newline at end of file diff --git a/js/review/reviewForm/useDeleteModal.js b/js/review/reviewForm/useDeleteModal.js new file mode 100644 index 0000000..c7e1586 --- /dev/null +++ b/js/review/reviewForm/useDeleteModal.js @@ -0,0 +1,32 @@ +const useDeleteModal = ({name, onSubmit}) => { + const modal = createModal(name); + + modal.addEventListener('click', (event) => { + if (event.target.id === name || event.target.className === 'close-button') { + modal.parentNode.removeChild(modal); + } + }); + + modal.querySelector('#modalForm').addEventListener('submit',(event) => { + event.preventDefault(); + onSubmit(); + }); + + return modal; +} + +const createModal = (id) => { + const modal = document.createElement('div'); + modal.id = id; + modal.innerHTML = ` +
    + 삭제하시겠어요? + + + +
    + `; + return modal; +}; + +export default useDeleteModal; \ No newline at end of file diff --git a/js/review/reviewForm/utils.js b/js/review/reviewForm/utils.js index d7332f9..4a09b1d 100644 --- a/js/review/reviewForm/utils.js +++ b/js/review/reviewForm/utils.js @@ -26,3 +26,15 @@ const addCommentToExisting = ({comments, index, values}) => { updatedComments[index].results.push(values); return updatedComments; }; + +const deleteReview = ({reviews, deleteIndex}) => reviews.filter((_, i) => i !== deleteIndex); + +export const deleteReviewToLocalStorage = (deleteIndex) => { + const movieId = getMovieIdFromURL(); + let comments = getDetailComments(); + const {index: currentMovieIndex} = getExistingDetailComments({comments, movieId}); + + comments[currentMovieIndex].results = deleteReview({reviews: comments[currentMovieIndex].results, deleteIndex}); + + setDetailComments(comments); +} \ No newline at end of file From aa747b4d8a3a252e962b15f9a6c074a4ca4a7f56 Mon Sep 17 00:00:00 2001 From: Yerin Date: Mon, 6 May 2024 18:12:11 +0900 Subject: [PATCH 3/4] =?UTF-8?q?fix:=20=ED=8C=9D=EC=97=85=20DOM=20=EC=9A=94?= =?UTF-8?q?=EC=86=8C=EA=B0=80=20=EA=B7=B8=EB=A0=A4=EC=A7=84=20=EC=83=81?= =?UTF-8?q?=ED=83=9C=EB=9D=BC=EB=A9=B4=20=EC=A4=91=EB=B3=B5=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EA=B7=B8=EB=A0=A4=EC=A7=80=EB=8A=94=20=EA=B2=83?= =?UTF-8?q?=EC=9D=84=20=EB=A7=89=EB=8A=94=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- js/review/reviewForm/deleteReviewHandler.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/js/review/reviewForm/deleteReviewHandler.js b/js/review/reviewForm/deleteReviewHandler.js index cb09bde..a15a543 100644 --- a/js/review/reviewForm/deleteReviewHandler.js +++ b/js/review/reviewForm/deleteReviewHandler.js @@ -3,23 +3,27 @@ import {isValidPassword} from "./isValidReviewValues.js"; import {notifyAndReload} from "../utils.js"; import useDeleteModal from "./useDeleteModal.js"; +const POPUP_NAME = 'popup'; + const deleteReviewHandler = () => { - const handleButtonClick = (event) => { + const onClick = (event) => { + const popup = document.getElementById(POPUP_NAME); + if (popup) return; + const index = parseInt(event.target.closest('.comment-util').dataset.index); const modal = useDeleteModal({ - name: 'popup', + name: POPUP_NAME, onSubmit: () => onSubmit({passwordInput, index}) }); const passwordInput = modal.querySelector('.text-input[type=password]'); - passwordInput.focus(); document.getElementById('reviewContainer').appendChild(modal); }; document.querySelectorAll('.comment-util .delete-btn') - .forEach(btn => btn.addEventListener('click', handleButtonClick)); + .forEach(btn => btn.addEventListener('click', onClick)); }; const onSubmit = ({passwordInput, index}) => { From 3cd538ac508ab2687d11fbfdcece9c099b673b7e Mon Sep 17 00:00:00 2001 From: Yerin Date: Mon, 6 May 2024 18:55:38 +0900 Subject: [PATCH 4/4] =?UTF-8?q?style:=20=ED=95=A8=EC=88=98=20=EB=82=B4?= =?UTF-8?q?=EB=B6=80=EB=A1=9C=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- js/review/index.js | 4 +--- js/review/reviewList/renderMovieReviews.js | 5 ++++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/js/review/index.js b/js/review/index.js index db9d9b1..be925de 100644 --- a/js/review/index.js +++ b/js/review/index.js @@ -1,11 +1,9 @@ import starRatingHandler from './reviewForm/starRatingHandler.js'; import writeReviewHandler from './reviewForm/writeReviewHandler.js'; import renderMovieReviews from "./reviewList/renderMovieReviews.js"; -import getMovieReviews from "./reviewList/getMovieReviews.js"; import deleteReviewHandler from "./reviewForm/deleteReviewHandler.js"; -const reviews = getMovieReviews(); -renderMovieReviews(reviews); +renderMovieReviews(); starRatingHandler(); writeReviewHandler(); deleteReviewHandler(); \ No newline at end of file diff --git a/js/review/reviewList/renderMovieReviews.js b/js/review/reviewList/renderMovieReviews.js index 4792515..ad7f61c 100644 --- a/js/review/reviewList/renderMovieReviews.js +++ b/js/review/reviewList/renderMovieReviews.js @@ -1,4 +1,7 @@ -const renderMovieReviews = (reviews = []) => { +import getMovieReviews from "./getMovieReviews.js"; + +const renderMovieReviews = () => { + const reviews = getMovieReviews(); const $wrap = document.querySelector('#reviewList'); if (reviews.length === 0) {