From 4124be0938871d34ab6c38772f4d7400ccd4a811 Mon Sep 17 00:00:00 2001 From: inyoung Date: Sun, 24 Mar 2024 14:31:04 +0900 Subject: [PATCH 01/36] =?UTF-8?q?Feat:=20=EC=B5=9C=EA=B7=BC=20=EC=88=9C,?= =?UTF-8?q?=20=EC=9D=BD=EC=A7=80=20=EC=95=8A=EC=9D=80=20=EC=88=9C=20?= =?UTF-8?q?=EB=AA=A8=EB=8B=AC=20=EA=B3=B5=EA=B0=9C=EC=83=81=EB=8B=B4=20?= =?UTF-8?q?=ED=83=AD=EC=97=90=EC=84=9C=20=EA=B5=AC=ED=98=84=20#180?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SellerConsult/SellerConsultSection.tsx | 15 ++++--- .../SellerConsult/SellerOpenConsultList.tsx | 42 ++++++++++++++++++- src/hooks/useConsultParams.ts | 6 +-- src/pages/Buyer/BuyerConsult.tsx | 8 ++-- 4 files changed, 58 insertions(+), 13 deletions(-) diff --git a/src/components/Seller/SellerConsult/SellerConsultSection.tsx b/src/components/Seller/SellerConsult/SellerConsultSection.tsx index 012bdb62..6d726f2b 100644 --- a/src/components/Seller/SellerConsult/SellerConsultSection.tsx +++ b/src/components/Seller/SellerConsult/SellerConsultSection.tsx @@ -23,7 +23,7 @@ export const SellerConsultSection = () => { setSortType, handleLetterClick, handleChatClick, - handleOpenChatClick, + handleOpenConsultClick, searchParams, setSearchParams, isChecked, @@ -50,8 +50,8 @@ export const SellerConsultSection = () => { 공개상담 @@ -66,7 +66,7 @@ export const SellerConsultSection = () => { - {!(consultType === 'open-chat') && ( + {!(consultType === 'open-consult') && (
{ isChecked={isChecked} /> ) : ( - + )} ); diff --git a/src/components/Seller/SellerConsult/SellerOpenConsultList.tsx b/src/components/Seller/SellerConsult/SellerOpenConsultList.tsx index 10d1063c..d4929c8c 100644 --- a/src/components/Seller/SellerConsult/SellerOpenConsultList.tsx +++ b/src/components/Seller/SellerConsult/SellerOpenConsultList.tsx @@ -11,8 +11,31 @@ import { ReactComponent as CommentIcon } from 'assets/icons/icon-comment.svg'; import { ReactComponent as CheckIcon } from 'assets/icons/icon-check2.svg'; import { Space } from 'components/Common/Space'; import { LoadingSpinner } from 'utils/LoadingSpinner'; -function SellerOpenConsultList() { +import { SetURLSearchParams } from 'react-router-dom'; +import { isConsultModalOpenState, scrollLockState } from 'utils/atom'; +import { useRecoilState, useSetRecoilState } from 'recoil'; +import { BackDrop } from 'components/Common/BackDrop'; +import { ConsultModal } from 'components/Buyer/BuyerConsult/ConsultModal'; + +interface SellerConsultOpenProps { + sortType: number; + setSortType: React.Dispatch>; + searchParams: URLSearchParams; + setSearchParams: SetURLSearchParams; +} + +function SellerOpenConsultList({ + sortType, + setSortType, + searchParams, + setSearchParams, +}: SellerConsultOpenProps) { const [isLoading, setIsLoading] = useState(false); + const [isModalOpen, setIsModalOpen] = useRecoilState( + isConsultModalOpenState, + ); + const setScrollLock = useSetRecoilState(scrollLockState); + const fetchOpenConsultData = async () => {}; return ( <> @@ -77,6 +100,23 @@ function SellerOpenConsultList() { )} + + {isModalOpen ? ( + <> + { + setIsModalOpen(false); + setScrollLock(false); + }} + /> + + + ) : null} ); } diff --git a/src/hooks/useConsultParams.ts b/src/hooks/useConsultParams.ts index 36b63fbe..3c69a047 100644 --- a/src/hooks/useConsultParams.ts +++ b/src/hooks/useConsultParams.ts @@ -33,8 +33,8 @@ export const useConsultParams = () => { setSearchParams(searchParams); }; - const handleOpenChatClick = () => { - setConsultType('open-chat'); + const handleOpenConsultClick = () => { + setConsultType('open-consult'); searchParams.set('type', 'open-consult'); setSearchParams(searchParams); }; @@ -44,7 +44,7 @@ export const useConsultParams = () => { sortType, setSortType, handleLetterClick, - handleOpenChatClick, + handleOpenConsultClick, handleChatClick, searchParams, setSearchParams, diff --git a/src/pages/Buyer/BuyerConsult.tsx b/src/pages/Buyer/BuyerConsult.tsx index af19cca0..f3742045 100644 --- a/src/pages/Buyer/BuyerConsult.tsx +++ b/src/pages/Buyer/BuyerConsult.tsx @@ -37,7 +37,7 @@ export const BuyerConsult = () => { sortType, setSortType, handleLetterClick, - handleOpenChatClick, + handleOpenConsultClick, handleChatClick, searchParams, setSearchParams, @@ -80,10 +80,10 @@ export const BuyerConsult = () => { - + 공개상담 From 292179cff614e754a8f0b09cfbfc1db31699bef3 Mon Sep 17 00:00:00 2001 From: inyoung Date: Sun, 24 Mar 2024 16:19:05 +0900 Subject: [PATCH 02/36] =?UTF-8?q?Feat:=20=EB=A7=88=EC=9D=B8=EB=8D=94=20?= =?UTF-8?q?=EA=B3=B5=EA=B0=9C=EC=83=81=EB=8B=B4=20=ED=83=AD=20=EB=A7=88?= =?UTF-8?q?=ED=81=AC=EC=97=85=20=EC=99=84=EB=A3=8C=20#180?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SellerOpenConsult/BottomSection.tsx | 118 ++++++++++++++ .../SellerOpenConsult/CommentListSection.tsx | 146 ++++++++++++++++++ .../Seller/SellerOpenConsult/IsSendPopup.tsx | 96 ++++++++++++ .../SellerOpenConsult/MainQuestionSection.tsx | 38 ++++- src/components/Seller/SellerOpenConsult/S= | 1 + src/pages/Seller/SellerOpenConsult.tsx | 16 ++ src/utils/atom.ts | 5 + 7 files changed, 417 insertions(+), 3 deletions(-) create mode 100644 src/components/Seller/SellerOpenConsult/BottomSection.tsx create mode 100644 src/components/Seller/SellerOpenConsult/CommentListSection.tsx create mode 100644 src/components/Seller/SellerOpenConsult/IsSendPopup.tsx create mode 100644 src/components/Seller/SellerOpenConsult/S= diff --git a/src/components/Seller/SellerOpenConsult/BottomSection.tsx b/src/components/Seller/SellerOpenConsult/BottomSection.tsx new file mode 100644 index 00000000..a0a21681 --- /dev/null +++ b/src/components/Seller/SellerOpenConsult/BottomSection.tsx @@ -0,0 +1,118 @@ +import { Button } from 'components/Common/Button'; +import React, { useState } from 'react'; +import reactTextareaAutosize from 'react-textarea-autosize'; +import styled from 'styled-components'; +import { ReactComponent as SendIcon } from 'assets/icons/icon-send.svg'; +import { Green, Grey3, Grey6, LightGreen, White } from 'styles/color'; +import { useRecoilValue, useSetRecoilState } from 'recoil'; +import { isSendPopupOpenState } from 'utils/atom'; + +function BottomSection() { + const [isReplying, setIsReplying] = useState(false); + const [text, setText] = useState(''); + const setIsSendPopupOpen = useSetRecoilState(isSendPopupOpenState); + return ( + + {isReplying ? ( +
+ { + setText(e.target.value); + }} + rows={1} + maxRows={4} + /> + 0 ? Green : Grey3} + onClick={() => { + // sendMessage(); + setIsSendPopupOpen(true); + }} + /> +
+ ) : ( +
+
+ )} +
+ ); +} + +const BottomSectionWrapper = styled.section` + display: flex; + flex-direction: column; + align-items: center; + box-shadow: 0px 0px 2px 0px rgba(0, 0, 0, 0.25); + background-color: white; + text-align: center; + gap: 0.6rem; + padding-top: 0.8rem; + padding-bottom: 1.6rem; + background-color: ${White}; + position: fixed; + bottom: 0; + width: 100%; + .buttons { + display: flex; + justify-content: center; + gap: 0.7rem; + width: calc(100% - 4rem); + } + .message-input { + display: flex; + width: calc(100% - 4rem); + align-items: center; + gap: 0.8rem; + } + @media (max-width: 767px) { + width: calc(100%); + } + @media (min-width: 768px) { + width: calc(375px); + } +`; + +const MessageTextArea = styled(reactTextareaAutosize)` + width: 100%; + padding: 1.2rem 1.5rem; + outline: none; + border: none; + resize: none; + border-radius: 1.2rem; + background-color: ${Grey6}; + font-family: Pretendard; + font-size: 1.6rem; + font-style: normal; + font-weight: 400; + line-height: 110%; /* 1.76rem */ + &:focus { + border: none; + outline: none; + } +`; +const SendIconSVG = styled(SendIcon)` + cursor: pointer; + align-self: flex-end; + padding-bottom: 0.7rem; +`; + +export default BottomSection; diff --git a/src/components/Seller/SellerOpenConsult/CommentListSection.tsx b/src/components/Seller/SellerOpenConsult/CommentListSection.tsx new file mode 100644 index 00000000..7557db64 --- /dev/null +++ b/src/components/Seller/SellerOpenConsult/CommentListSection.tsx @@ -0,0 +1,146 @@ +import { lightGreen } from '@mui/material/colors'; +import { light } from '@mui/material/styles/createPalette'; +import React from 'react'; +import styled from 'styled-components'; +import { + Green, + Grey1, + Grey2, + Grey3, + Grey6, + LightGreen, + LightRed, +} from 'styles/color'; +import { Body1, Body3, Body4, Caption1, Caption2 } from 'styles/font'; +import { ReactComponent as HeartIcon } from 'assets/icons/icon-heart1.svg'; +import { ReactComponent as HeartEmptyIcon } from 'assets/icons/icon-heart3.svg'; +import { ReactComponent as SettingIcon } from 'assets/icons/icon-option.svg'; +import { Characters } from 'utils/Characters'; +import { Space } from 'components/Common/Space'; + +function CommentListSection() { + return ( + + + + 아직 답장한 마인더가 없어요! 가장 먼저 답장해보세요. + + + {/* 댓글 리스트 , 최대 5개까지*/} + +
+ + 연애상담마스터 + + 11:23 + +
+ + + 권태기 증상이 맞는 것 같네요. 속상하시겠지만, 대화를 통해 충분히 + 극복하실 수 있어요. 어쩌구 저쩌구. + + + + 28 + +
+ +
+ + 연애상담마스터 + + 11:23 + +
+ + + 권태기 증상이 맞는 것 같네요. 속상하시겠지만, 대화를 통해 충분히 + 극복하실 수 있어요. 어쩌구 저쩌구. + + + + 28 + +
{' '} + +
+ + 연애상담마스터 + + 11:23 + +
+ + + 권태기 증상이 맞는 것 같네요. 속상하시겠지만, 대화를 통해 충분히 + 극복하실 수 있어요. 어쩌구 저쩌구. + + + + 28 + +
+ +
+ ); +} + +const CommentListSectionWrapper = styled.section` + padding: 1.2rem 2rem; + display: flex; + flex-direction: column; + gap: 0.6rem; +`; + +const CommentGuide = styled.div<{ $isGreen: boolean }>` + height: 3.1rem; + background-color: ${(props) => (props.$isGreen ? LightGreen : LightRed)}; + display: flex; + justify-content: center; + align-items: center; + border-radius: 0.8rem; +`; + +const CommentCard = styled.div` + display: flex; + position: relative; + border-radius: 1.2rem; + box-sizing: border-box; + padding: 1.2rem 1.6rem; + flex-direction: column; + align-items: flex-start; + background-color: ${Grey6}; + gap: 1rem; + .flex1 { + display: flex; + width: 100%; + gap: 0.8rem; + height: 3.3rem; + align-items: center; + } +`; + +const LikeButton = styled.div` + display: flex; + border-radius: 0.8rem; + background-color: white; + padding: 0.4rem 0.8rem 0.4rem 0.4rem; + align-items: center; + gap: 0.4rem; +`; + +const Circle = styled.div` + width: 0.2rem; + height: 0.2rem; + border-radius: 100%; + background-color: ${Grey3}; +`; + +const SettingButton = styled(SettingIcon)` + position: absolute; + top: 2.65rem; + right: 2rem; +`; + +export default CommentListSection; diff --git a/src/components/Seller/SellerOpenConsult/IsSendPopup.tsx b/src/components/Seller/SellerOpenConsult/IsSendPopup.tsx new file mode 100644 index 00000000..557127c0 --- /dev/null +++ b/src/components/Seller/SellerOpenConsult/IsSendPopup.tsx @@ -0,0 +1,96 @@ +import React from 'react'; +import { useNavigate } from 'react-router-dom'; +import { useSetRecoilState } from 'recoil'; +import styled from 'styled-components'; +import { Green, Grey4, LightGreen, White } from 'styles/color'; +import { Body1, Body3 } from 'styles/font'; +import { isSendPopupOpenState } from 'utils/atom'; + +function IsSendPopup() { + const navigate = useNavigate(); + const setIsSendPopupOpen = useSetRecoilState(isSendPopupOpenState); + const handleSendContent = () => {}; + return ( + + + 설정을 저장하지 않고 나가시겠습니까? + 저장하지 않으면 작성한 설정이 초기화됩니다. + + { + setIsSendPopupOpen(false); + }} + > + 아니오 + + + + + + ); +} +const IsSendModalBox = styled.div` + width: 100%; + height: 15rem; + z-index: 9999; + display: flex; + justify-content: center; + position: absolute; + top: 22.3rem; + @media (max-width: 767px) { + width: 100vw; + } + @media (min-width: 768px) { + width: 37.5rem; + } +`; + +const ModalBox = styled.div` + background: ${White}; + padding: 2rem; + border-radius: 1.2rem; + box-sizing: border-box; + padding: 1.6rem; + display: flex; + flex-direction: column; + align-items: center; + box-shadow: 0px 0px 20px 0px rgba(0, 0, 0, 0.1); + text-align: center; +`; + +const ButtonWrapper = styled.div` + margin-top: 2rem; + display: flex; + gap: 0.7rem; + font-size: 1.6rem; + font-weight: 600; +`; + +const NoButton = styled.div` + display: flex; + width: 14.8rem; + height: 5.2rem; + cursor: pointer; + border-radius: 0.8rem; + padding: 1.7rem 0rem 1.5rem 0rem; + justify-content: center; + align-items: center; + color: ${Green}; + background-color: ${LightGreen}; + box-sizing: border-box; +`; + +const YesButton = styled.div` + display: flex; + width: 14.8rem; + height: 5.2rem; + border-radius: 0.8rem; + padding: 1.7rem 0rem 1.5rem 0rem; + cursor: pointer; + justify-content: center; + align-items: center; + color: ${White}; + background-color: ${Green}; + box-sizing: border-box; +`; +export default IsSendPopup; diff --git a/src/components/Seller/SellerOpenConsult/MainQuestionSection.tsx b/src/components/Seller/SellerOpenConsult/MainQuestionSection.tsx index bfb26528..c8089dbc 100644 --- a/src/components/Seller/SellerOpenConsult/MainQuestionSection.tsx +++ b/src/components/Seller/SellerOpenConsult/MainQuestionSection.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useState } from 'react'; import styled from 'styled-components'; import { Grey1, Grey2, Grey3, Grey6 } from 'styles/color'; import { ReactComponent as LockIcon } from 'assets/icons/icon-lock.svg'; @@ -11,6 +11,8 @@ import { ReactComponent as CheckIcon } from 'assets/icons/icon-check2.svg'; import { Body1, Caption1, Caption2 } from 'styles/font'; import { Space } from 'components/Common/Space'; function MainQuestionSection() { + const [isSave, setIsSave] = useState(false); + const [isLike, setIsLike] = useState(false); return ( @@ -39,11 +41,37 @@ function MainQuestionSection() { - + {isLike ? ( + { + setIsLike(false); + }} + /> + ) : ( + { + setIsLike(true); + }} + /> + )} + 11 - + {isSave ? ( + { + setIsSave(false); + }} + /> + ) : ( + { + setIsSave(true); + }} + /> + )} + 0 @@ -108,4 +136,8 @@ const ButtonItem = styled.div` gap: 0.4rem; `; +const SaveResizeIcon = styled(SaveIcon)` + width: 2rem; + height: 2rem; +`; export default MainQuestionSection; diff --git a/src/components/Seller/SellerOpenConsult/S= b/src/components/Seller/SellerOpenConsult/S= new file mode 100644 index 00000000..991aa1a5 --- /dev/null +++ b/src/components/Seller/SellerOpenConsult/S= @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/pages/Seller/SellerOpenConsult.tsx b/src/pages/Seller/SellerOpenConsult.tsx index 2b3af7f1..51c50494 100644 --- a/src/pages/Seller/SellerOpenConsult.tsx +++ b/src/pages/Seller/SellerOpenConsult.tsx @@ -1,13 +1,29 @@ +import { BackDrop } from 'components/Common/BackDrop'; +import BottomSection from 'components/Seller/SellerOpenConsult/BottomSection'; +import CommentListSection from 'components/Seller/SellerOpenConsult/CommentListSection'; +import IsSendPopup from 'components/Seller/SellerOpenConsult/IsSendPopup'; import MainQuestionSection from 'components/Seller/SellerOpenConsult/MainQuestionSection'; import MainQuestion from 'components/Seller/SellerOpenConsult/MainQuestionSection'; import OpenConsultHeader from 'components/Seller/SellerOpenConsult/OpenConsultHeader'; import React from 'react'; +import { useRecoilValue } from 'recoil'; +import { isSendPopupOpenState } from 'utils/atom'; function SellerOpenConsult() { + const isSendPopupOpen = useRecoilValue(isSendPopupOpenState); + return ( <> + + + {isSendPopupOpen && ( + <> + + + + )} ); } diff --git a/src/utils/atom.ts b/src/utils/atom.ts index e44c0f1f..af6bc515 100644 --- a/src/utils/atom.ts +++ b/src/utils/atom.ts @@ -44,6 +44,11 @@ export const isOutPopupOpenState = atom({ default: false, }); +export const isSendPopupOpenState = atom({ + key: 'isOutPopupOpenState', + default: false, +}); + export const isSuccessUpdateState = atom({ key: 'isSuccessUpdateState', default: false, From c043b1c6b6dfb075e253578dd736ff6d7debdfd1 Mon Sep 17 00:00:00 2001 From: inyoung Date: Mon, 25 Mar 2024 00:22:52 +0900 Subject: [PATCH 03/36] =?UTF-8?q?Feat:=20=EA=B5=AC=EB=A7=A4=EC=9E=90=20?= =?UTF-8?q?=EA=B3=B5=EA=B0=9C=EC=83=81=EB=8B=B4=20=ED=83=AD=20=EB=A7=88?= =?UTF-8?q?=ED=81=AC=EC=97=85=20=EC=99=84=EB=A3=8C=20#180?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/assets/icons/icon-write.svg | 4 + .../BuyerConsult/BuyerOpenConsultSection.tsx | 186 ++++++++++++++++++ .../Buyer/BuyerConsult/IsBuyPopup.tsx | 95 +++++++++ src/components/Seller/SellerOpenConsult/S= | 1 - src/pages/Buyer/BuyerConsult.tsx | 3 +- src/pages/Buyer/BuyerOpenConsult.tsx | 8 +- src/utils/atom.ts | 5 + 7 files changed, 295 insertions(+), 7 deletions(-) create mode 100644 src/assets/icons/icon-write.svg create mode 100644 src/components/Buyer/BuyerConsult/BuyerOpenConsultSection.tsx create mode 100644 src/components/Buyer/BuyerConsult/IsBuyPopup.tsx delete mode 100644 src/components/Seller/SellerOpenConsult/S= diff --git a/src/assets/icons/icon-write.svg b/src/assets/icons/icon-write.svg new file mode 100644 index 00000000..38341f86 --- /dev/null +++ b/src/assets/icons/icon-write.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/components/Buyer/BuyerConsult/BuyerOpenConsultSection.tsx b/src/components/Buyer/BuyerConsult/BuyerOpenConsultSection.tsx new file mode 100644 index 00000000..23119f41 --- /dev/null +++ b/src/components/Buyer/BuyerConsult/BuyerOpenConsultSection.tsx @@ -0,0 +1,186 @@ +import React, { useState } from 'react'; +import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil'; +import styled from 'styled-components'; +import { Green, Grey1, Grey2, Grey3, Grey6 } from 'styles/color'; +import { Body1, Caption1, Caption2 } from 'styles/font'; +import { LoadingSpinner } from 'utils/LoadingSpinner'; +import { + isBuyPopupOpenState, + isConsultModalOpenState, + scrollLockState, +} from 'utils/atom'; +import { ReactComponent as LockIcon } from 'assets/icons/icon-lock.svg'; +import { ReactComponent as HeartIcon } from 'assets/icons/icon-heart2.svg'; +import { ReactComponent as HeartEmptyIcon } from 'assets/icons/icon-heart3.svg'; +import { ReactComponent as SaveIcon } from 'assets/icons/icon-save2.svg'; +import { ReactComponent as SaveEmptyIcon } from 'assets/icons/icon-save3.svg'; +import { ReactComponent as CommentIcon } from 'assets/icons/icon-comment.svg'; +import { ReactComponent as CheckIcon } from 'assets/icons/icon-check2.svg'; +import { ReactComponent as WriteIcon } from 'assets/icons/icon-write.svg'; +import { Space } from 'components/Common/Space'; +import { BackDrop } from 'components/Common/BackDrop'; +import IsBuyPopup from './IsBuyPopup'; + +function BuyerOpenConsultSection() { + const [isLoading, setIsLoading] = useState(false); + const [isModalOpen, setIsModalOpen] = useRecoilState( + isConsultModalOpenState, + ); + const setScrollLock = useSetRecoilState(scrollLockState); + const [isBuyPopupOpen, setIsBuyPopupOpen] = + useRecoilState(isBuyPopupOpenState); + const handleWritePostButton = () => { + setIsBuyPopupOpen(true); + }; + return ( + <> + {isLoading ? ( +
+ +
+ ) : ( + + {/* 상담카드 부분 */} + +
+ 이거 권태기 증상 맞나요? + + + 비공개 + +
+ +
+ 요즘따라 여자친구가 먼저 만나자고 이야기도 안 하고 만나면 + 피곤하다고만 해요. 스킨십도 하려고 하지 않고 인생이 재미가 + 없다네요.. 그런데 여자친구가 다른 남자 인스타 피드에는 좋아요를 + 눌러요... 이거 여자친구가 권태기가 맞는 걸까요? 맞다면 어떻게 + 이야기를 꺼내면 좋을까요? 너무 힘듭니다.. +
+
+ + + 28 + + + + 28 + + + + 28 + +
+ 8분 전 +
+ {/* 상담카드 부분 */} +
+ )}{' '} + {isBuyPopupOpen && ( + <> + + + + )} + + + + + + + ); +} + +const BuyerOpenConsultCardList = styled.div` + display: flex; + margin: 0 2rem; + flex-direction: column; + align-items: flex-start; + gap: 1.2rem; +`; + +const BuyerOpenConsultCard = styled.div` + width: 100%; + height: 14rem; + position: relative; + background-color: ${Grey6}; + padding: 1.6rem; + box-sizing: border-box; + border-radius: 1.2rem; + .row2 { + display: -webkit-box; + max-height: 4.7rem; + -webkit-box-orient: vertical; + overflow: hidden; + align-self: flex-end; + margin-bottom: 0.4rem; + -webkit-line-clamp: 2; + color: ${Grey1}; + height: 4.6rem; + text-overflow: ellipsis; + font-family: Pretendard; + font-size: 1.4rem; + font-style: normal; + font-weight: 400; + line-height: 155%; + } + .row3 { + display: flex; + gap: 1.2rem; + } +`; +const IconItem = styled.div` + display: flex; + align-items: center; + gap: 0.5rem; +`; + +const HeartResizeIcon = styled(HeartIcon)` + width: 2rem; + height: 2rem; +`; + +const PrivateSign = styled.div` + display: flex; + position: absolute; + top: 1.95rem; + right: 1.6rem; +`; + +const TimeLeft = styled.div` + font-size: 1.2rem; + font-weight: 400; + color: ${Grey2}; + position: absolute; + bottom: 1.8rem; + right: 1.6rem; +`; + +const CreateConsultButton = styled.button` + width: 5.8rem; + height: 5.8rem; + border-radius: 100%; + background-color: ${Green}; + box-shadow: 0px 0px 12px 0px rgba(0, 0, 0, 0.25); + align-self: flex-end; +`; +const CreateConsultButtonWrapper = styled.div` + width: 100%; + padding: 0 3.3rem; + box-sizing: border-box; + display: flex; + position: fixed; + bottom: 3.5rem; + flex-direction: column; + @media (min-width: 768px) { + width: 375px; + } +`; + +export default BuyerOpenConsultSection; diff --git a/src/components/Buyer/BuyerConsult/IsBuyPopup.tsx b/src/components/Buyer/BuyerConsult/IsBuyPopup.tsx new file mode 100644 index 00000000..ec7aebe8 --- /dev/null +++ b/src/components/Buyer/BuyerConsult/IsBuyPopup.tsx @@ -0,0 +1,95 @@ +import React from 'react'; +import { useNavigate } from 'react-router-dom'; +import { useSetRecoilState } from 'recoil'; +import styled from 'styled-components'; +import { Green, Grey4, LightGreen, White } from 'styles/color'; +import { Body1, Body3 } from 'styles/font'; +import { isBuyPopupOpenState, isSendPopupOpenState } from 'utils/atom'; + +function IsBuyPopup() { + const navigate = useNavigate(); + const setIsSendPopupOpen = useSetRecoilState(isBuyPopupOpenState); + const handleBuyConsult = () => {}; + return ( + + + 상담권 구매 후 글을 작성할 수 있어요. + + { + setIsSendPopupOpen(false); + }} + > + 닫기 + + 구매하기 + + + + ); +} +const IsSendModalBox = styled.div` + width: 100%; + height: 12.8rem; + z-index: 9999; + display: flex; + justify-content: center; + position: absolute; + top: 22.3rem; + @media (max-width: 767px) { + width: 100vw; + } + @media (min-width: 768px) { + width: 37.5rem; + } +`; + +const ModalBox = styled.div` + background: ${White}; + padding: 2rem; + border-radius: 1.2rem; + box-sizing: border-box; + padding: 1.6rem; + display: flex; + flex-direction: column; + align-items: center; + box-shadow: 0px 0px 20px 0px rgba(0, 0, 0, 0.1); + text-align: center; +`; + +const ButtonWrapper = styled.div` + margin-top: 2rem; + display: flex; + gap: 0.7rem; + font-size: 1.6rem; + font-weight: 600; +`; + +const NoButton = styled.div` + display: flex; + width: 14.8rem; + height: 5.2rem; + cursor: pointer; + border-radius: 0.8rem; + padding: 1.7rem 0rem 1.5rem 0rem; + justify-content: center; + align-items: center; + color: ${Green}; + background-color: ${LightGreen}; + box-sizing: border-box; +`; + +const YesButton = styled.div` + display: flex; + width: 14.8rem; + height: 5.2rem; + border-radius: 0.8rem; + padding: 1.7rem 0rem 1.5rem 0rem; + cursor: pointer; + justify-content: center; + align-items: center; + color: ${White}; + background-color: ${Green}; + box-sizing: border-box; +`; +export default IsBuyPopup; diff --git a/src/components/Seller/SellerOpenConsult/S= b/src/components/Seller/SellerOpenConsult/S= deleted file mode 100644 index 991aa1a5..00000000 --- a/src/components/Seller/SellerOpenConsult/S= +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/pages/Buyer/BuyerConsult.tsx b/src/pages/Buyer/BuyerConsult.tsx index f3742045..f999fc73 100644 --- a/src/pages/Buyer/BuyerConsult.tsx +++ b/src/pages/Buyer/BuyerConsult.tsx @@ -13,6 +13,7 @@ import { ConsultModal } from 'components/Buyer/BuyerConsult/ConsultModal'; import { BuyerChatSection } from 'components/Buyer/BuyerConsult/BuyerChatSection'; import { BuyerLetterSection } from 'components/Buyer/BuyerConsult/BuyerLetterSection'; import { useConsultParams } from 'hooks/useConsultParams'; +import BuyerOpenConsultSection from 'components/Buyer/BuyerConsult/BuyerOpenConsultSection'; export interface consultApiObject { consultStyle: string; @@ -118,7 +119,7 @@ export const BuyerConsult = () => { ) : consultType === 'chat' ? ( ) : ( - '컴포넌트 만들면 후에 추가' + )} {isModalOpen ? ( <> diff --git a/src/pages/Buyer/BuyerOpenConsult.tsx b/src/pages/Buyer/BuyerOpenConsult.tsx index 82b787dd..1d503949 100644 --- a/src/pages/Buyer/BuyerOpenConsult.tsx +++ b/src/pages/Buyer/BuyerOpenConsult.tsx @@ -1,9 +1,7 @@ -import React from 'react' +import React from 'react'; function BuyerOpenConsult() { - return ( -
BuyerOpenConsult
- ) + return
BuyerOpenConsult
; } -export default BuyerOpenConsult \ No newline at end of file +export default BuyerOpenConsult; diff --git a/src/utils/atom.ts b/src/utils/atom.ts index af6bc515..940c6960 100644 --- a/src/utils/atom.ts +++ b/src/utils/atom.ts @@ -49,6 +49,11 @@ export const isSendPopupOpenState = atom({ default: false, }); +export const isBuyPopupOpenState = atom({ + key: 'isBuyPopupOpenState', + default: false, +}); + export const isSuccessUpdateState = atom({ key: 'isSuccessUpdateState', default: false, From ed9c9684e7b7c29f3f76d6056c264e01b71d532b Mon Sep 17 00:00:00 2001 From: inyoung Date: Mon, 25 Mar 2024 01:27:29 +0900 Subject: [PATCH 04/36] =?UTF-8?q?Feat:=20=EA=B5=AC=EB=A7=A4=EC=9E=90=20?= =?UTF-8?q?=EA=B3=B5=EA=B0=9C=20=EC=83=81=EB=8B=B4=20=EA=B2=B0=EC=A0=9C=20?= =?UTF-8?q?=ED=94=8C=EB=A1=9C=EC=9A=B0=20=EA=B5=AC=ED=98=84=20#180?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Router.tsx | 7 + .../Buyer/BuyerConsult/IsBuyPopup.tsx | 4 +- src/pages/Buyer/BuyerOpenConsultRequest.tsx | 118 +++++++ src/pages/Buyer/BuyerOpenPaymentDetail.tsx | 310 ++++++++++++++++++ 4 files changed, 438 insertions(+), 1 deletion(-) create mode 100644 src/pages/Buyer/BuyerOpenConsultRequest.tsx create mode 100644 src/pages/Buyer/BuyerOpenPaymentDetail.tsx diff --git a/src/Router.tsx b/src/Router.tsx index c331e6c1..de23dd3a 100644 --- a/src/Router.tsx +++ b/src/Router.tsx @@ -47,6 +47,8 @@ import { BuyerQuit } from 'pages/Buyer/BuyerQuit'; import { SellerChatTemp } from 'pages/Seller/SellerChatTemp'; import BuyerOpenConsult from 'pages/Buyer/BuyerOpenConsult'; import SellerOpenConsult from 'pages/Seller/SellerOpenConsult'; +import { BuyerOpenConsultRequest } from 'pages/Buyer/BuyerOpenConsultRequest'; +import { BuyerOpenPaymentDetail } from 'pages/Buyer/BuyerOpenPaymentDetail'; const Router = () => { return ( @@ -62,6 +64,11 @@ const Router = () => { } /> } /> } /> + + } /> + + } /> + } /> } /> } /> diff --git a/src/components/Buyer/BuyerConsult/IsBuyPopup.tsx b/src/components/Buyer/BuyerConsult/IsBuyPopup.tsx index ec7aebe8..cef43925 100644 --- a/src/components/Buyer/BuyerConsult/IsBuyPopup.tsx +++ b/src/components/Buyer/BuyerConsult/IsBuyPopup.tsx @@ -9,7 +9,9 @@ import { isBuyPopupOpenState, isSendPopupOpenState } from 'utils/atom'; function IsBuyPopup() { const navigate = useNavigate(); const setIsSendPopupOpen = useSetRecoilState(isBuyPopupOpenState); - const handleBuyConsult = () => {}; + const handleBuyConsult = () => { + navigate('/openConsultRequest'); + }; return ( diff --git a/src/pages/Buyer/BuyerOpenConsultRequest.tsx b/src/pages/Buyer/BuyerOpenConsultRequest.tsx new file mode 100644 index 00000000..b55150e3 --- /dev/null +++ b/src/pages/Buyer/BuyerOpenConsultRequest.tsx @@ -0,0 +1,118 @@ +import { BackIcon, HeaderWrapper } from 'components/Buyer/Common/Header'; +import { Button } from 'components/Common/Button'; +import { useEffect, useState } from 'react'; +import { useLocation, useNavigate } from 'react-router-dom'; +import styled from 'styled-components'; +import { Green, Grey1, Grey2, Grey6, LightGreen } from 'styles/color'; +import { Body2, Heading } from 'styles/font'; + +export const BuyerOpenConsultRequest = () => { + const navigate = useNavigate(); + const [isOpenConsult, setIsOpenConsult] = useState(false); + const [isNotOpenConsult, setIsNotOpenConsult] = useState(false); + const [buttonAcitve, setButtonAcitve] = useState(false); + const location = useLocation(); + const handleNextClick = () => { + if (buttonAcitve) { + if (isOpenConsult) { + } else { + navigate('/openPaymentDetail'); + } + } + }; + useEffect(() => { + if (!(isOpenConsult === false && isNotOpenConsult === false)) { + setButtonAcitve(true); + } else { + setButtonAcitve(false); + } + }, [isOpenConsult, isNotOpenConsult]); + return ( + + + { + navigate("/consult"); + }} + /> + 일대다상담 신청하기 + +
+
+
+ + 상담 방식을 선택해주세요. + +
+ + { + setIsOpenConsult(true); + setIsNotOpenConsult(false); + }} + > + + 공개 + + 이건 무료에요. + + { + setIsOpenConsult(false); + setIsNotOpenConsult(true); + }} + > + + 비공개 + + + 이건 유료에요. 마인더들만 내 고민을 보고 답변할 수 있다. 다른 + 셰어들은 못본다. + + +
+
+
+ ); +}; +const Wrapper = styled.div` + .headline { + width: 89.33%; + } + .body-wrapper { + height: calc(var(--vh, 1vh) * 100 - 7.1rem); + display: flex; + flex-direction: column; + align-items: center; + justify-content: space-between; + } + .content { + display: flex; + flex-direction: column; + align-items: center; + } +`; +const Box = styled.div<{ focus: boolean }>` + padding: 1.6rem; + width: 89.33%; + background-color: ${(props) => (props.focus ? LightGreen : Grey6)}; + border: ${(props) => + props.focus ? `1px solid ${Green}` : `1px solid ${Grey6}`}; + border-radius: 1.2rem; + box-sizing: border-box; + margin-bottom: 1.2rem; + cursor: pointer; +`; diff --git a/src/pages/Buyer/BuyerOpenPaymentDetail.tsx b/src/pages/Buyer/BuyerOpenPaymentDetail.tsx new file mode 100644 index 00000000..8dcd3833 --- /dev/null +++ b/src/pages/Buyer/BuyerOpenPaymentDetail.tsx @@ -0,0 +1,310 @@ +import { Button } from 'components/Common/Button'; +import styled from 'styled-components'; +import { Green, Grey1, Grey3, Grey6, LightGreen, White } from 'styles/color'; +import { Body1, Body3, Heading } from 'styles/font'; +import { ReactComponent as Heart } from 'assets/icons/icon-payment-detail-heart.svg'; +import { useLocation, useNavigate, useParams } from 'react-router-dom'; +import { useEffect, useState } from 'react'; +import { BackIcon, HeaderWrapper } from 'components/Buyer/Common/Header'; + +export const BuyerOpenPaymentDetail = () => { + const navigate = useNavigate(); + const [buttonSelect, setButtonSelect] = useState(0); + const handlePaymentClick = () => { + navigate('/paymentComplete'); + }; + return ( + + + { + navigate('/openConsultRequest'); + }} + /> + 상담 신청하기 + +
+ +
+ + 상담 유형 + + + 공개상담 - 공개 +
+
+ +
+ + 상담료 + +
+
+ + 상품 금액 + + + 500원 + +
+
+ + 할인 금액 + + + 0원 + +
+ +
+ + 결제 금액 + + + 500원 + +
+
+ +
+ + 결제 방법 + +
+
+
+ {buttonSelect === 1 ? ( +
+
+ {buttonSelect === 3 ? ( +
+
+ {buttonSelect === 5 ? ( +
+
+
+ +
+ + 이용 안내 + +
+
+
+ + + 주문을 완료하시면 필요 시 결제 사이트로 이동합니다. + +
+
+ +
+ + 상담 시작 전 구매자 혹은 판매자 요청에 의해 상담이 취소될 수 + 있으며 이 경우 결제금액은 환불신청을 해 주시면 환불 처리해 + 드립니다. + +
+
+
+ +
+ + 판매자의 응답 시간 경과로 상담이 취소될 경우 환불신청을 + 해주시면 환불 처리해 드립니다. + +
+
+
+ +
+ + 상담이 시작되면 취소 및 환불이 제한됩니다. 이미 시작된 상담의 + 환불처리의 경우 신고하기를 통해 분쟁접수를 해주시기 바랍니다. + +
+
+
+ +
+ + 상담을 마치고 24시간 이내 판매자가 상담완료를 누르지 않으면 + 거래가 자동 완료됩니다. + +
+
+
+ +
+ + 상담 완료 후 7일간 거래 확정을 하지 않으면 자동 거래 + 확정됩니다. + +
+
+
+
+
+ +
{isModalOpen ? ( <> @@ -282,6 +260,28 @@ export const BuyerLetterWrite = () => { }} /> ) : null} + +