From f82ab650e00d3a7c2d09c23403614c2d800a034d Mon Sep 17 00:00:00 2001 From: jaesjeon Date: Fri, 29 Jul 2022 21:54:20 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EB=B0=94=EC=9D=B8=EB=94=A9=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=ED=8C=9D=EC=97=85=20=EA=B5=AC=ED=98=84=5F?= =?UTF-8?q?url,=20title,=20=EC=8B=B1=EA=B8=80=ED=8E=98=EC=9D=B4=EC=A7=80?= =?UTF-8?q?=20=EC=88=9C=EC=84=9C=20=EB=B0=9B=EC=95=84=EC=84=9C=20API?= =?UTF-8?q?=EC=9A=94=EC=B2=AD=20=EA=B0=80=EB=8A=A5=5F=EB=AF=B8=EB=A6=AC?= =?UTF-8?q?=EB=B3=B4=EA=B8=B0,=20=EC=84=A0=ED=83=9D=EB=90=9C=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=EC=97=90=20=EC=98=A4=EB=B2=84=EB=A0=88?= =?UTF-8?q?=EC=9D=B4=20=EA=B5=AC=ED=98=84=20=ED=95=84=EC=9A=94=20#234?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/MyPage/BindingPopUp.jsx | 270 ++++++++++++++++++ src/components/MyPage/BindingPreview.jsx | 12 + .../MyPage/BindingSelectSinglePages.jsx | 64 +++++ .../MyPage/BindingSinglePageBlock.jsx | 46 +++ src/pages/MyPage.js | 45 ++- 5 files changed, 433 insertions(+), 4 deletions(-) create mode 100644 src/components/MyPage/BindingPopUp.jsx create mode 100644 src/components/MyPage/BindingPreview.jsx create mode 100644 src/components/MyPage/BindingSelectSinglePages.jsx create mode 100644 src/components/MyPage/BindingSinglePageBlock.jsx diff --git a/src/components/MyPage/BindingPopUp.jsx b/src/components/MyPage/BindingPopUp.jsx new file mode 100644 index 00000000..748ea444 --- /dev/null +++ b/src/components/MyPage/BindingPopUp.jsx @@ -0,0 +1,270 @@ +/** @jsxImportSource @emotion/react */ +import { css } from '@emotion/react'; +import React, { useState, useRef, useEffect } from 'react'; +import useRequestAuth from '../../hooks/useRequestAuth'; +import { useGetPersonalUrl } from '../../hooks/useParamsUrl'; +import { getApiEndpoint } from '../../utils/util'; +import BindingPreview from './BindingPreview'; +import BindingSelectSinglePages from './BindingSelectSinglePages'; + +function BindingPopUp({ userSeq, popUp, setPopUp }) { + const [inputs, setInputs] = useState({ + title: '', + url: '', + thumbnail: '', + singlePages: [], + }); + const [paddingSize, setPaddingSize] = useState(0); + const [selectedPages, setSelectedPages] = useState([]); + + const endpoint = `${getApiEndpoint()}/user/page/multi/${userSeq}`; + // eslint-disable-next-line no-unused-vars + const { res, request } = useRequestAuth({ + endpoint: endpoint, + method: 'post', + data: inputs, + }); + + const pageUrl = useGetPersonalUrl(); + const fixedTextRef = useRef(null); + useEffect(() => { + setPaddingSize(fixedTextRef.current.clientWidth + 1); + }, []); + useEffect(() => { + setInputs({ + ...inputs, + singlePages: { selectedPages }, + }); + }, [selectedPages]); + + const { title, url } = inputs; + + const onChange = (e) => { + const { name, value } = e.target; + setInputs({ + ...inputs, + [name]: value, + }); + }; + function onChangeForm(event) { + // eslint-disable-next-line no-unused-vars + event.preventDefault(); + request(); + setPopUp(!popUp); + } + + console.log(inputs); + return ( +
+
+
페이지 합치기
+
+ +
+
+ +
+
+
+
페이지 주소
+
+ + https://iamonit.kr/{pageUrl}/ + + +
+
+
+
페이지 제목
+ +
+
+
페이지 선택
+
+ +
+
+ +
+
+
+
+
+ ); +} + +export default BindingPopUp; + +const backGroundPopStyle = css` + position: fixed; + top: 0px; + left: 0px; + width: 100vw; + height: 100vh; + background-color: rgba(0, 0, 0, 0.2); + flex-direction: column; + align-items: center; + justify-content: center; +`; + +const pagePopUpBoxStyle = css` + position: fixed; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + width: 980px; + height: 584px; + background-color: #ffffff; + box-shadow: 10px 10px 10px 10px rgba(0, 0, 0, 0.16); + border-radius: 20px; +`; + +const pagePopUpBoxTitle = css` + font-size: 30px; + text-align: center; + font-weight: bold; + margin-top: 45px; +`; + +const pagePopUpBoxContentsWraper = css` + display: flex; + flex-direction: row; + align-items: stretch; + width: 100%; + justify-content: space-between; + text-align: center; +`; + +const pagePopUpBoxContents = css` + font-size: 15px; + line-height: 30px; + font-weight: bold; + margin-top: 47px; + margin-left: 5px; + margin-right: 0px; +`; + +const formText = css` + position: relative; +`; + +const pagePopUpBoxInput = css` + width: 330px; + height: 40px; + border-radius: 20px; + background-color: white; + font-size: 15px; + box-sizing: border-box; + border: none; + text-indent: 15px; + margin-right: 50px; + margin-top: 40px; + box-shadow: 0 3px 30px 0 rgba(0, 0, 0, 0.07); + :focus { + box-shadow: 0 3px 30px 0 rgba(0, 0, 0, 0.18); + } +`; + +const fixedText = css` + position: absolute; + left: 15px; + top: 50px; + color: gray; + z-index: 9; +`; + +const formWidth = css` + width: 100%; + height: 85%; +`; + +const AddButtonStyle = css` + position: absolute; + left: 650px; + top: 480px; + width: 15%; + height: 50px; + border-radius: 30px; + border: 0; + font-weight: bold; + font-size: 20px; +`; + +const pagePopUpBoxCloseButton = css` + width: 3%; + height: 30px; + border-radius: 30px; + border: 0; + position: absolute; + left: 95%; + top: 3%; + font-size: 15px; + margin-bottom: 10px; + background-color: lightgray; + &:hover { + background-color: darkgray; + } +`; + +const LoginButtonColor = css` + color: rgba(255, 255, 255, 1); + background-color: rgba(239, 100, 8, 1); + &:hover { + background-color: rgba(300, 100, 8, 1); + } +`; + +const HorizontalLayout = css` + display: flex; + flex-direction: row; + align-items: baseline; + text-align: center; +`; + +const PreviewWidth = css` + width: 50%; +`; + +const InputWidth = css` + width: 50%; +`; + +const SelectSinglePagesLayout = css` + margin-right: 50px; + margin-top: 40px; + width: 330px; + height: 210px; +`; diff --git a/src/components/MyPage/BindingPreview.jsx b/src/components/MyPage/BindingPreview.jsx new file mode 100644 index 00000000..05838560 --- /dev/null +++ b/src/components/MyPage/BindingPreview.jsx @@ -0,0 +1,12 @@ +/** @jsxImportSource @emotion/react */ +import { css } from '@emotion/react'; + +const BindingPreview = () => { + return
미리보기 영역
; +}; + +export default BindingPreview; + +const previewLayout = css` + height: 100%; +`; diff --git a/src/components/MyPage/BindingSelectSinglePages.jsx b/src/components/MyPage/BindingSelectSinglePages.jsx new file mode 100644 index 00000000..09cb81a7 --- /dev/null +++ b/src/components/MyPage/BindingSelectSinglePages.jsx @@ -0,0 +1,64 @@ +/** @jsxImportSource @emotion/react */ +import { css } from '@emotion/react'; +import React, { useState, useEffect } from 'react'; +import { useSelector } from 'react-redux'; +import BindingSinglePageBlock from './BindingSinglePageBlock'; + +const BindingSelectSinglePages = ({ selectedPages, setSelectedPages }) => { + const { singlePages } = useSelector((state) => ({ + singlePages: state.info.singlePages, + })); + const singlePagesInfo = singlePages.data; + + function handleSelect(selectedPageUrl) { + let newSinglePageList; + if ( + selectedPages.filter( + (element) => element.singlePageUrl === selectedPageUrl + ).length === 0 + ) { + newSinglePageList = [ + ...selectedPages, + { singlePageUrl: selectedPageUrl }, + ]; + } else { + newSinglePageList = selectedPages.filter( + (element) => element.singlePageUrl !== selectedPageUrl + ); + } + setSelectedPages(newSinglePageList); + } + + return singlePages.data.length !== 0 ? ( +
+ {singlePagesInfo.map((page, index) => { + const semiIndex = index + 1; + return ( +
+ +
+ ); + })} +
+ ) : ( +
싱글 페이지가 없습니다!
+ ); +}; + +export default BindingSelectSinglePages; + +const siteViewBZone = css` + display: flex; + height: 100%; + justify-content: flex-start; + align-items: flex-start; + overflow: scroll; + margin-top: 5px; + margin-bottom: 5px; + background-color: white; +`; + +const noneSinglePageMsg = css` + display: block; + margin-top: 10px; +`; diff --git a/src/components/MyPage/BindingSinglePageBlock.jsx b/src/components/MyPage/BindingSinglePageBlock.jsx new file mode 100644 index 00000000..e701da8b --- /dev/null +++ b/src/components/MyPage/BindingSinglePageBlock.jsx @@ -0,0 +1,46 @@ +/** @jsxImportSource @emotion/react */ +import { css } from '@emotion/react'; +import React from 'react'; + +const BindingSinglePageBlock = (props) => { + const thumbnailUrl = + props.data.thumbnail !== '' + ? props.data.thumbnail + : 'https://mblogthumb-phinf.pstatic.net/MjAxNzA2MjNfNDEg/MDAxNDk4MjExMTE1OTYy.RGjgC51-8rYSISInewpiERaIWLuYkk6h8-DHImZWlNog.6nJ1cYNwJuFRBYbzuXIlfFC2vAz9SSYihxEpnVX2ttUg.PNG.kkp0079/1.PNG?type=w800'; + + return ( +
props.handleSelect(props.data.url)} + onKeyDown={() => props.handleSelect(props.data.url)} + > + +
{props.data.title}
+
+ ); +}; + +export default BindingSinglePageBlock; + +const thumbnailImg = css` + width: 100px; + height: 80%; + border-radius: 20px 20px 0px 0px; + object-fit: cover; +`; + +const singlePageBox = css` + width: 100px; + height: 160px; + border: 10px black; + border-radius: 20px; + margin-right: 5px; +`; + +const singlePageTitle = css` + font-size: 15px; + margin: auto; + margin-top: 5px; + margin-bottom: 10px; + overflow: hidden; +`; diff --git a/src/pages/MyPage.js b/src/pages/MyPage.js index e617dfcb..d2dc7dc3 100644 --- a/src/pages/MyPage.js +++ b/src/pages/MyPage.js @@ -2,10 +2,11 @@ import { css } from '@emotion/react'; import { useEffect, useState } from 'react'; import { useHistory } from 'react-router'; - +import { useDispatch } from 'react-redux'; import { Header } from '../components'; import AddPagePopUp from '../components/MyPage/AddPagePopUp'; import EditPropfilePopUp from '../components/MyPage/EditProfilePopUp'; +import BindingPagePopUp from '../components/MyPage/BindingPopUp'; import PageBlock from '../components/MyPage/PageBlock'; import { useMyInfo } from '../hooks/myInfo'; import { useRequest } from '../hooks/useRequest'; @@ -26,6 +27,7 @@ import ProfileBlock from '../components/MyPage/ProfileBlock'; // import MyPageComment from '../components/MyPage/MyPageComment'; // import MyPageCommentWrite from '../components/MyPage/MyPageCommentWrite'; // import MyPageProfile from '../components/MyPage/MyPageProfile'; +import { createReplacementSinglePagesAction } from '../redux/slice'; function MyPage() { // const [localFiles, setLocalFiles] = useState(null); @@ -45,6 +47,8 @@ function MyPage() { const [nickname, setNickname] = useState(null); const [popUp, setPopUp] = useState(false); const [profilePopUp, setProfilePopUp] = useState(false); + const [bindingPopUp, setBindingPopUp] = useState(false); + const dispatch = useDispatch(); const { res: pageUserRes, request: requestPageUserInfo } = useRequest({ endpoint: `${getApiEndpoint()}/url/${pageUrl}/user`, @@ -54,7 +58,12 @@ function MyPage() { // eslint-disable-next-line no-unused-vars const { res: bZoneData, request: requestBZoneData } = useRequest({ - endpoint: `${getApiEndpoint()}/user/page/single/${userSeq}`, + endpoint: `${getApiEndpoint()}/user/page/singles/${userSeq}`, + method: 'get', + }); + + const { res: singlePagesData, request: requestSinglePagesData } = useRequest({ + endpoint: `${getApiEndpoint()}/user/page/singles/${userSeq}`, method: 'get', }); @@ -71,7 +80,10 @@ function MyPage() { if (myInfo && urlMatched(myInfo.url, pageUrl)) { setUserMatched(true); setNickname(myInfo.nickname); - if (userSeq) requestBZoneData(); + if (userSeq) { + requestBZoneData(); + requestSinglePagesData(); + } // 다른 사람 페이지일 경우 } else { @@ -107,6 +119,12 @@ function MyPage() { }; }, [pageUserRes]); + // 바인딩 페이지용 싱글페이지 목록 데이터 리덕스에 저장 + useEffect(() => { + if (singlePagesData && singlePagesData.data) { + dispatch(createReplacementSinglePagesAction(singlePagesData.data)); + } + }, [singlePagesData]); // const users = [ // { title: 'arch', url: 'arch1', index: 4, delete: 'n' }, // { title: 'movie', url: 'movie1', index: 2, delete: 'n' }, @@ -259,10 +277,17 @@ function MyPage() { text-align: center; `} > + {/*
팔로우
*/} @@ -291,7 +316,12 @@ function MyPage() { })} */} {/* {console.log(users)} */} {bzoneimage()} - +
@@ -319,6 +349,13 @@ function MyPage() { popUp={profilePopUp} /> )} + {bindingPopUp && ( + + )} {popUp && ( )}